gpt4 book ai didi

c# - 将异步上传到 Azure Blob 存储永远不会返回

转载 作者:行者123 更新时间:2023-12-02 02:43:05 24 4
gpt4 key购买 nike

我尝试使用异步方法将文件上传到 Azure Blob 存储,然后设置其元数据,但 UploadFromByteArrayAsync 方法永远不会返回。

我有以下代码:

var connAzureBlob = ConfigurationManager.AppSettings["AzureBlobStorage"];    
var storageAccount = CloudStorageAccount.Parse(connAzureBlob);
var blobClient = storageAccount.CreateCloudBlobClient();

var fileContainer = blobClient.GetContainerReference(ConfigurationManager.AppSettings["AzureBlobContainer"]);
if (!fileContainer.Exists())
{
await fileContainer.CreateAsync();
await fileContainer.SetPermissionsAsync(new BlobContainerPermissions {
PublicAccess = BlobContainerPublicAccessType.Blob
});
}

try
{
var fileBlob = fileContainer.GetBlockBlobReference(documentId.ToString());
await fileBlob.UploadFromByteArrayAsync(buffer, 0, buffer.Length);
Log.Info($"{nameof(SaveToBlobAsync)}: blob {documentId} uploaded.");

await fileBlob.FetchAttributesAsync();
fileBlob.Properties.ContentType = contentType;
fileBlob.Metadata["..."] = "...";
await fileBlob.SetMetadataAsync();
Log.Info($"{nameof(SaveToBlobAsync)}: {documentId} - metadata saved.");
}
catch (Exception exception)
{
Log.Error($"{nameof(SaveToBlobAsync)}: An exception was thrown while saving a file to a blob: ", exception);
throw;
}

使用上面的代码,我希望看到记录以下消息:

SaveToBlobAsync: blob 123 uploaded.
SaveToBlobAsync: 123 - metadata saved.

但这些从未出现。

但是,该 blob 似乎已存储(我可以使用 Azure Storage Explorer 查看其内容),但该过程似乎没有移动到下一行(这将是第一条日志记录消息)。

如果我将所有异步调用切换为非异步调用,那么代码将按预期工作。

谁能解释为什么 UploadFromByteArrayAsync 似乎没有返回?

更新:我想我应该添加一些有关上下文的更多信息,以防有帮助。

此代码是从 Web API 方法调用的。有问题的 Controller 没有异步代码,除了调用存储库方法之外几乎不执行任何其他操作。存储库方法在调用与 blob 存储接口(interface)的类之前更新 SQL DB(同样,所有这些都是非异步代码)。

这个面向 blob 存储的类具有非异步方法,除了使用 .Wait().Result 调用其异步等效方法之外,几乎没有其他作用。

在本例中,第二阶段的存储库正在调用非异步版本,因此上面的代码本质上是通过 .Wait() 调用的。

在执行上述代码之前,此 HTTP 请求从进入 Web API Controller 的那一刻起,就没有其他异步调用。

最佳答案

该错误几乎肯定是在调用堆栈的更上方,其中某些方法阻塞了返回的任务(例如 Task<T>.ResultTask.Wait 等)。如果任务需要被阻塞的线程才能完成,这将导致死锁。

I explain this situation in full on my blog ,但要点是:

  • await默认情况下将捕获“上下文”并使用它来恢复 async方法。
  • 如果此代码在 ASP.NET 请求上下文中执行,则此“上下文”是 ASP.NET SynchronizationContext ;如果此代码在 UI 线程中执行,则此“上下文”是 UI SynchronizationContext .
  • 两者都是 ASP.NET SynchronizationContext和用户界面SynchronizationContext一次只允许其中有一个线程。

因此,当调用代码在返回的 Task阻塞时,它在该上下文中持有一个线程,从而防止 Task从完成。

关于c# - 将异步上传到 Azure Blob 存储永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com