【问题标题】:Azure Blob Storage DownloadToStreamAsync hangs during network changeAzure Blob 存储 DownloadToStreamAsync 在网络更改期间挂起
【发布时间】:2019-11-04 13:21:41
【问题描述】:

我遇到了Microsoft.WindowsAzure.Storage v9.3.3Microsoft.Azure.Storage.Blob v11.1.0 NuGet 库的问题。特别是在下载大文件时。如果您在“DownloadToStreamAsync”方法期间更改网络,呼叫将挂起。我一直看到我的代码处理大量文件,它偶尔会挂起,我一直在尝试缩小范围。我认为网络更改可能是触发 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 或我在使用此包时缺少的东西吗?

【问题讨论】:

  • 那么你的问题是什么?
  • 抱歉,我现在已经编辑了我的帖子。我想知道我还能做些什么吗?

标签: c# azure azure-blob-storage


【解决方案1】:

感谢 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");

【讨论】:

    猜你喜欢
    • 2014-01-17
    • 2015-04-16
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多