[BUG] .Net Framework hanging on BlobClient.DownloadAsync
See original GitHub issueDescribe the bug I am trying to download large blobs in chunks. I have the same exact code in a .Net 4.7.2 Framework console app and an .Net Core 3.1 console app. The .Net Core app works fine, the .Net Framework app ends up hanging on one of the download calls and eventually throws an error after it is retried 6 times.
This looks similar to Issue # 10027. The comments there try to imply that it is a network or host issue, but perhaps my example will help you reproduce the issue.
In my test I am attempting to download a blob that is 880MB in size.
Expected behavior The downloads should work correctly in .Net Framework
Actual behavior (include Exception or Stack Trace) A few download calls complete successfully before getting this error (I only included 1 of the inner exceptions, there are 6 of them):
System.AggregateException: Retry failed after 6 tries. β> System.Threading.Tasks.TaskCanceledException: A task was canceled. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpClientTransport.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessNextAsync>d__10.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessAsync>d__9.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__5.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__3.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__7.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.<ProcessAsync>d__1.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext() β End of inner exception stack trace β at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.<ProcessAsync>d__1.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.<ProcessAsync>d__1.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Storage.Blobs.BlobRestClient.Blob.<DownloadAsync>d__0.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Storage.Blobs.Specialized.BlobBaseClient.<StartDownloadAsync>d__45.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadInternal>d__44.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadAsync>d__43.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at SafeguardControllerBusinessLogic.AzureStorageBusinessLogic.<DownloadImportBackupAsync>d__1.MoveNext() in C:\projects\Safeguard\SafeguardControllerBusinessLogic\AzureStorageBusinessLogic.cs:line 98 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at SafeguardControllerBusinessLogic.ControllerHelperFunctions.<ImportDatabasesAsync>d__39.MoveNext() in C:\projects\Safeguard\SafeguardControllerBusinessLogic\SafeguardControllerBusinessLogicClassLibrary.cs:line 1762 β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at SafeguardController.ViewModels.ImportGroupsSettingsViewModel.<ImportDatabaseAsync>d__77.MoveNext() in C:\projects\Safeguard\SafeguardController\ViewModels\ImportGroupsSettingsViewModel.cs:line 547 β> (Inner Exception #0) System.Threading.Tasks.TaskCanceledException: A task was canceled. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpClientTransport.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessNextAsync>d__10.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessAsync>d__9.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__5.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__3.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__7.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.<ProcessAsync>d__1.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext()<ββ> (Inner Exception #1) System.Threading.Tasks.TaskCanceledException: A task was canceled. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpClientTransport.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessNextAsync>d__10.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RequestActivityPolicy.<ProcessAsync>d__9.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__5.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.ResponseBodyPolicy.<ProcessAsync>d__3.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__7.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.LoggingPolicy.<ProcessAsync>d__6.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.<ProcessAsync>d__1.MoveNext() β End of stack trace from previous location where exception was thrown β at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext()<β
To Reproduce Here is my sample app, same exact code in the .Net Framework 4.7.2 app and .Net Core 3.1 app. Iβve added the Azure.Storage.Blobs NuGet package version 12.4.1 to both. The sasURL string is a SAS string to one of my Azure storage containers. Iβm trying to download in chunks so that I can display progress to the user.
static async Task Main(string[] args)
{
string sasUrl = @"<sas string here>";
BlobContainerClient blobContainerClient = new BlobContainerClient(new Uri(sasUrl), null);
//create a blob client
BlockBlobClient blockBlobClient = blobContainerClient.GetBlockBlobClient(@"Backups/SGDataMar022020.wtsbak");
var properties = await blockBlobClient.GetPropertiesAsync();
int chunkSize = 5 * 1024 * 1024; //5MB in bytes
long fileSize = properties.Value.ContentLength;
long blobLengthRemaining = fileSize; //bytes of file to download
string fileName = Path.Combine(@"C:\Users\bkoth\Documents", @"Backups/SGDataMar022020.wtsbak");
long totalChunks = (fileSize - 1) / chunkSize + 1;
long startPosition = 0;
int chunkIndex = 1;
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
if (File.Exists(fileName))
{
File.Delete(fileName);
}
do
{
long blockSize = Math.Min(chunkSize, blobLengthRemaining);
var response = await blockBlobClient.DownloadAsync(
range: new Azure.HttpRange(startPosition, blockSize)
);
byte[] buffer = new byte[blockSize];
await response.Value.Content.ReadAsync(buffer: buffer,
offset: 0,
count: buffer.Length
);
using (FileStream fileStream = new FileStream(path: fileName, mode: FileMode.OpenOrCreate))
{
fileStream.Position = startPosition;
await fileStream.WriteAsync(buffer: buffer,
offset: 0,
count: buffer.Length);
}
startPosition += blockSize;
blobLengthRemaining -= blockSize;
double percent = (((double)chunkIndex) / (double)totalChunks) * 100;
Console.WriteLine(string.Format("Percent complete: {0}%", Convert.ToInt32(percent)));
chunkIndex++;
} while (blobLengthRemaining > 0);
}
Environment: Azure.Storage.Blobs 12.4.1 .NET Core SDK (reflecting any global.json): Version: 3.1.100 Commit: cd82f021f4
Runtime Environment: OS Name: Windows OS Version: 10.0.17134 OS Platform: Windows RID: win10-x64 Visual Studio 16.4.2
Issue Analytics
- State:
- Created 3 years ago
- Comments:28 (20 by maintainers)
Top GitHub Comments
@bruckGT Iβve been playing with your sample and was able to repro. Iβd recommend to change the following line:
to:
i.e. make sure to dispose Response Stream when youβre done reading it. Otherwise it stays open and blocks the connection.
Please update to https://www.nuget.org/packages/Azure.Storage.Blobs/12.4.4 https://www.nuget.org/packages/Azure.Storage.Common/12.4.3