网络更改期间Azure Blob存储DownloadToStreamAsync挂起

我遇到了Microsoft.WindowsAzure.Storage v9.3.3Microsoft.Azure.Storage.Blob v11.1.0 NuGet库的问题。特别是在下载大文件时。如果您在“ DownloadToStreamAsync”方法期间更改网络,则调用将挂起。我一直在查看处理文件 lot 的代码,该代码偶尔会挂起,并且一直在尝试缩小范围。我认为网络更改可能是触发Azure Blob存储库中某些故障的可靠方法。

有关此问题的更多信息;

  • 拔下网络电缆时,我的计算机切换为WiFi,但请求永远不会恢复
  • 如果我开始通过WiFi下载,然后插入网络电缆,则会发生相同的错误
  • “ ServerTimeout”属性绝不会失败请求,也不会按照Documentation
  • 的预期进行操作
  • “ MaximumExecutionTime”属性确实使请求失败,但我们不想将自己限制在某个时间段内,特别是因为我们正在处理大文件

如果在通话过程中更改了网络,以下代码将在100%的时间内失败。

static void Main(string[] args)
{
    try
    {
        CloudStorageaccount.TryParse("<Connection String>",out var storageaccount);
        var cloudBlobClient = storageaccount.CreatecloudBlobClient();
        var container = cloudBlobClient.getcontainerReference("<Container Reference>");
        var blobRef = container.GetBlockBlobReference("Large Text.txt");
        Stream memoryStream = new MemoryStream();
        BlobRequestOptions optionsWithRetryPolicy = new BlobRequestOptions() { ServerTimeout = TimeSpan.FromSeconds(5),RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(20),4) };
        blobRef.DownloadToStreamAsync(memoryStream,null,optionsWithRetryPolicy,null).Getawaiter().GetResult();
        Console.WriteLine("Completed");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
    }
    finally
    {
        Console.WriteLine("Finished");
    }
}

我在Azure存储GitHub中找到了this active issue,但它似乎没有激活。

在使用此软件包时,我还可以采取其他方法来可靠,有效地下载blob或缺少的东西吗?

qq393901347 回答:网络更改期间Azure Blob存储DownloadToStreamAsync挂起

根据我的研究,除**MaximumExecutionTime**之外,目前尚无此支持。最大执行时间是为单个API调用分配的时间。如果在所有REST请求,重试等过程中在API中花费的总时间超过该值,则客户端将超时。此值仅在客户端上跟踪,不会发送到服务。

目前,您可以监视下载到流中的数据量,如果一段时间内完全没有数据下载,则可以取消任务。**MaximumExecutionTime**将为您指定最大数量的上限API在超时之前失败所需的时间。 MaximumExecutionTime是允许操作的总时间,包括重试。即使传入数据包完全丢失,这也会导致请求超时。

其他参考:

https://social.msdn.microsoft.com/Forums/SqlServer/en-US/124261bf-bf78-4410-a892-86d574e94f6b/download-hangs-when-network-cable-unplugged?forum=windowsazuredata

https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.blob.blobrequestoptions.maximumexecutiontime?view=azure-dotnet

或者按照下面的帖子,您可以将blob文件分解成预期的部分,然后利用**CloudBlockBlob.DownloadRangeToStream**下载每个文件块。

https://stackoverflow.com/a/44384037/6049604

希望有帮助。

,

感谢Mohit的建议。

  • 创建任务以在后台检查流长度
  • 如果流在设置的时间内没有增加,请取消DownloadToStreamAsync

免责声明:我没有围绕此代码编写代码或如何以高效的方式运行它,因为您不必等待处理的每个文件都像这样。如果下载完成,我可能需要取消初始任务,我还不知道,我只是想先让它开始工作。我不认为它已经可以生产了。

// Create download cancellation token
var downloadCancellationTokenSource = new CancellationTokenSource();
var downloadCancellationToken = downloadCancellationTokenSource.Token;

var completedChecking = false;

// A background task to confirm the download is still progressing
Task.Run(() =>
{
    // Allow the download to start
    Task.Delay(TimeSpan.FromSeconds(2)).GetAwaiter().GetResult();

    long currentStreamLength = 0;
    var currentRetryCount = 0;
    var availableRetryCount = 5;

    // Keep the checking going during the duration of the Download
    while (!completedChecking)
    {
        Console.WriteLine("Checking");
        if (currentRetryCount == availableRetryCount)
        {
            Console.WriteLine($"RETRY WAS {availableRetryCount} - FAILING TASK");
            downloadCancellationTokenSource.Cancel();
            completedChecking = true;
        }

        if (currentStreamLength == memoryStream.Length)
        {
            currentRetryCount++;
            Console.WriteLine($"Length has not increased. Incremented Count: {currentRetryCount}");
            Task.Delay(TimeSpan.FromSeconds(10)).GetAwaiter().GetResult();
        }
        else
        {
            currentStreamLength = memoryStream.Length;
            Console.WriteLine($"Download in progress: {currentStreamLength}");
            currentRetryCount = 0;
            Task.Delay(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult();
        }
    }
});

Console.WriteLine("Starting Download");

blobRef.DownloadToStreamAsync(memoryStream,downloadCancellationToken).GetAwaiter().GetResult();

Console.WriteLine("Completed Download");
completedChecking = true;

Console.WriteLine("Completed");
本文链接:https://www.f2er.com/3166448.html

大家都在问