Parallel Blob Upload throwing 404 Bad Request intermittently

允我心安 提交于 2019-12-18 04:53:06

问题


I have a very simple service,

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

This method is called from,

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

My stream is HttpPostedFileBase.InputStream. Sometimes it works and sometimes I get The remote server returned an error: (400) Bad Request.. If I put a break-point it works as well.


回答1:


I had the same problem , I tried to upload 20 + images in 1 strike , single threaded works , multi threaded using await Task.WhenAll failed with "The remote server returned an error: (400) Bad Request."

  • see RequestInformation inside Microsoft.WindowsAzure.Storage.StorageException which is thrown from Upload[xxx]Async methods for more detailed information.

  • At first , RequestInformation said something about a MD5 problem with error code of "Md5Mismatch" , buy my intuition said otherwise because single thread works like a charm , and then .. I found it... DefaultRequestOptions.ParallelOperationThreadCount on CloudBlobClient object and problem sovled.

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



回答2:


The behaviour you are describing sounds very much like a threading problem (i.e. if you breakpoint the code it works fine as it's effectively single-threaded at that time) resulting in incomplete or invalid data being sent to the Azure Storage API.

Your "var image" definition may behave unexpectedly in a multi-threaded environment (If you utilised ReSharper it will highlight this variable and advise to change the code because it is potentially unsafe).

Have a read of this SO post to understand a little more and how you might better implement your code.

The foreach identifier and closures



来源:https://stackoverflow.com/questions/24229288/parallel-blob-upload-throwing-404-bad-request-intermittently

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!