并行Blob上传断断续续抛出404错误请求



我有一个很简单的服务,

public class AzureService : IAzureService
{
    private readonly CloudBlobContainer _container;
    public AzureService(ISettings settings)
    {
        var storageAccount = CloudStorageAccount.Parse(settings.BlobConnectionString);            
        var blobClient = storageAccount.CreateCloudBlobClient();
        _container = blobClient.GetContainerReference(settings.BlobContainerName);
    }
    public Task UploadBlobAsync(string fileName, Stream stream)
    {
        var blob = _container.GetBlockBlobReference(fileName);
        return blob.UploadFromStreamAsync(stream);
    }
    public Task DeleteBlobAsync(string fileName)
    {
        var blob = _container.GetBlockBlobReference(fileName);
        return blob.DeleteAsync();
    }
}

这个方法是从

    public Task SaveAllAsync(Dictionary<string, Stream> images)
    {
        var tasks = new List<Task>();
        foreach (var image in images)
        {
            var fileName = image.Key;
            var stream = image.Value;
            var task = _azureService.UploadBlobAsync(fileName, stream);
            tasks.Add(task);
        }
        return Task.WhenAll(tasks);
    }

我的流是httppostdfilebase . inputstream。有时它有效,有时我得到The remote server returned an error: (400) Bad Request.。如果我设置一个断点,它也可以工作

我有同样的问题,我试图在一次罢工中上传20 +图像,单线程作品,多线程使用await Task.WhenAll失败,"远程服务器返回错误:(400)错误请求。"

  • 参见RequestInformation中的Microsoft.WindowsAzure.Storage.StorageException,这是从上传[xxx]异步方法抛出的更详细的信息。

  • 起初,RequestInformation说了一些关于MD5问题的错误代码为"Md5Mismatch",但我的直觉告诉我,因为单线程工作就像一个魅力,然后…我找到了……DefaultRequestOptions.ParallelOperationThreadCount on CloudBlobClient object,问题解决

  • BlobRequestOptions Members MSDN


    private CloudBlobContainer ConnectToImageContainer()
    {
        var credentials = new StorageCredentials(AccountName, ImagesContainerKey);
        var account = new CloudStorageAccount(credentials, useHttps: true);
        var client = account.CreateCloudBlobClient();
        client.DefaultRequestOptions.ParallelOperationThreadCount = 64; // max value
        client.DefaultRequestOptions.SingleBlobUploadThresholdInBytes = 67108864; // max value
        var container = client.GetContainerReference(ImagesContainerName);
        return container;
    }

你所描述的行为听起来很像一个线程问题(即,如果你中断代码,它工作得很好,因为它当时是有效的单线程),导致不完整或无效的数据被发送到Azure存储API。

你的"var image"定义可能会在多线程环境中表现得出乎意料(如果你使用ReSharper,它会突出显示这个变量,并建议修改代码,因为它可能是不安全的)。

阅读这篇文章,了解更多,以及如何更好地实现你的代码。

foreach标识符和闭包

最新更新