I am trying to download a file from Azure blob, but in 0.1% cases it just hangs at the blockBlob.DownloadToStream(...) for more than 10 mins. Is there a way I can timeout this function in 2 mins?
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
using (var memoryStream = new System.IO.MemoryStream())
{
blockBlob.DownloadToStream(memoryStream, null, new BlobRequestOptions()
{
ServerTimeout = TimeSpan.FromSeconds(120)
});
string content = Encoding.UTF8.GetString(memoryStream.ToArray());
}
You can configure the timeout for the whole DownloadToStream operation. For example, you can set MaximumExecutionTime to 120 seconds (this is for whole DownloadToStream operation), ServerTimeout to 30 seconds (this is for each REST call), and specify a RetryPolicy (ExponentialRetry or LinearRetry, this is for each REST call) to enable retrying while a request times out or fails. By doing so, each individual Get Blob REST call will be limited to 30 seconds at server side (retry policy will take effect if encountering server timeout issue), and the whole DownloadToStream operation will be limited to 2 minutes at client side.
Please refer to the code sample below. Note: The BlobRequestOptions object only needs to be constructed once, then you can use it for all blob related operations below.
var maxRetryCount = 3;
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
var blobRequestOptions = new BlobRequestOptions
{
ServerTimeout = TimeSpan.FromSeconds(30),
MaximumExecutionTime = TimeSpan.FromSeconds(120),
RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(3), maxRetryCount),
};
using (var memoryStream = new MemoryStream())
{
blockBlob.DownloadToStream(memoryStream, null, blobRequestOptions);
}
Thanks! I also got the following piece of code to retry download the blob after a timeout.
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
var cts = new CancellationTokenSource((int)TimeSpan.FromSeconds(30 * (retryCount + 1)).TotalMilliseconds);
using (var memoryStream = new System.IO.MemoryStream())
{
Task task = blockBlob.DownloadToStreamAsync(memoryStream, cts.Token);
await task.ConfigureAwait(false);
if (!task.IsCanceled && !task.IsFaulted)
{
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
else if (task.IsCanceled)
{
retryCount++;
Console.WriteLine("Task cancelled happened for blob: {0}. Increasing timeout to: {1} sec", blobName, retryCount * 30);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With