在文件上传到Azure Blob存储期间“远程主机强行关闭了现有连接”

时间:2019-05-12 22:33:33

标签: azure azure-storage azure-storage-blobs blobstorage

我正在尝试使用Task.WhenAll(tasks);

将多个文件异步上传到Azure存储

但是,我一直遇到以下错误

Microsoft.WindowsAzure.Storage.StorageException
  HResult=0x80131500
  Message=Error while copying content to a stream.
  Source=Microsoft.WindowsAzure.Storage
  StackTrace:
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.<ExecuteAsyncInternal>d__4`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.<UploadFromStreamAsyncHelper>d__34.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.<UploadFromStreamAsyncHelper>d__33.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at RetsIntegration.Services.AzureBlobStorage.<CreateAsync>d__9.MoveNext() 

Inner Exception 1:
HttpRequestException: Error while copying content to a stream.

Inner Exception 2:
IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Inner Exception 3:
SocketException: An existing connection was forcibly closed by the remote host

执行任务几分钟后,就会发生错误。

我使用以下逻辑创建多个任务来上传图像

public async Task ProcessTasks(IEnumerable<FileObject> files)
{
    List<Task> tasks = new List<Task>();

    foreach (FileObject file in files)
    {
        string path = GetImageFullName(file, file.Filename);

        Task task Storage.CreateAsync(file.Content, path);

        tasks.Add(task);
    }

    // begings the upload to Azure
    await Task.WhenAll(tasks);
}

这是CreateAsync类中Storage方法的实现

public async Task CreateAsync(Stream stream, string path)
{
    var azure = GetAzurePath(path);
    // ContainerFactory is IBlobContainerFactory type
    var container = await ContainerFactory.GetAsync();

    CloudBlockBlob blockBlob = container.GetBlockBlobReference(azure);

    await blockBlob.UploadFromStreamAsync(stream);
}

这是我创建Blob容器的方法。请注意,在创建容器时,我将服务器超时增加到4小时,这应该是足够的时间来完成上传。

public class DefaultBlobContainerFactory : IBlobContainerFactory
{
    private readonly CloudBlobContainer _container;

    public DefaultBlobContainerFactory(AzureBlobOptions azureBlobOptions)
    {
        try
        {
            CloudBlobClient blobClient = GetClient(azureBlobOptions);
            _container = blobClient.GetContainerReference(azureBlobOptions.DocumentContainer);
        }
        catch (StorageException)
        {
            throw;
        }
    }

    protected virtual CloudBlobClient GetClient(AzureBlobOptions azureBlobOptions)
    {
        if (azureBlobOptions.ConnectionString != null && CloudStorageAccount.TryParse(azureBlobOptions.ConnectionString, out CloudStorageAccount cloudStorageAccount))
        {
            return cloudStorageAccount.CreateCloudBlobClient();
        }

        if (azureBlobOptions.BaseUri != null && azureBlobOptions.Token != null)
        {
            return new CloudBlobClient(azureBlobOptions.BaseUri, new StorageCredentials(azureBlobOptions.Token));
        }

        throw new ArgumentException("One of the following must be set: 'ConnectionString' or 'BaseUri'+'Token'!");
    }

    public async Task<CloudBlobContainer> GetAsync()
    {
        await _container.CreateIfNotExistsAsync(new BlobRequestOptions()
        {
            ServerTimeout = TimeSpan.FromHours(4),
        }, null);

        return _container;
    }
}

什么可能导致此问题?我该如何解决?

0 个答案:

没有答案