并行Blob上传间歇性地抛出404 Bad Request

时间:2014-06-15 11:47:36

标签: asp.net-mvc azure async-await azure-storage-blobs c#-5.0

我的服务很简单,

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

我的信息流是HttpPostedFileBase.InputStream。有时候它会起作用,有时候会得到The remote server returned an error: (400) Bad Request.。如果我提出一个断点也可以。

2 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,我试图在1次攻击中上传20 +图像,单线程工作,使用await Task.WhenAll多线程失败&#34;远程服务器返回错误:(400)错误请求&#34;

  • 请参阅RequestInformation内的Microsoft.WindowsAzure.Storage.StorageException,它是从上传[xxx]异步方法中引发的,以获取更多详细信息。

  • 首先,RequestInformation说了一个关于MD5问题的错误代码&#34; Md5Mismatch&#34; ,买我的直觉说不然,因为单线程就像一个魅力,然后......我发现它DefaultRequestOptions.ParallelOperationThreadCountCloudBlobClient对象和问题进行了解决。

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

答案 1 :(得分:0)

您所描述的行为听起来非常类似于线程问题(即,如果您断开代码,它可以正常工作,因为它当时有效地使用单线程)导致将不完整或无效的数据发送到Azure存储API。

你的&#34; var image&#34;定义在多线程环境中可能会出现意外行为(如果您使用了ReSharper,它将突出显示此变量并建议更改代码,因为它可能不安全)。

阅读此SO帖子以了解更多内容以及如何更好地实现代码。

The foreach identifier and closures