Azure blob DownloadToStream 耗时过长

Azure blob DownloadToStream takes too long

我正在尝试从 Azure blob 下载文件,但在 0.1% 的情况下它只是在 blockBlob.DownloadToStream(...) 处挂起超过 10 分钟。有没有办法让这个函数在 2 分钟内超时?

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());
}

您可以为整个 DownloadToStream 操作配置超时。例如,你可以设置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调用限制为30秒(如果遇到服务器超时问题,重试策略将生效),整个DownloadToStream操作在客户端限制为2分钟。

请参考下面的代码示例。注意:BlobRequestOptions对象只需要构造一次,下面所有的blob相关操作都可以使用它。

        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);
        }

谢谢!我还得到了以下代码,用于在超时后重试下载 blob。

 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);
    }
}