[英]Uploading async to Azure Blob Storage never returns
我正在嘗試使用異步方法將文件上載到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已上傳。
SaveToBlobAsync:123 - 保存元數據。
但這些從未出現過。
但是,blob似乎存儲(我可以使用Azure存儲資源管理器查看其內容),但該過程似乎沒有移動到下一行(這將是第一個日志消息)。
如果我為非異步對應方切換所有異步調用,則代碼按預期工作。
任何人都可以解釋為什么UploadFromByteArrayAsync
似乎沒有返回?
更新:我想我會添加一些關於上下文的更多信息,以防它有所幫助。
此代碼是從Web API方法調用的。 有問題的控制器沒有異步代碼,除了調用存儲庫方法之外別無其他。 存儲庫方法在調用與blob存儲接口的類之前更新SQL DB - 再次,所有這些都是非異步代碼。
這個面向blob存儲的類具有非異步方法,除了使用.Wait()
或.Result
調用它們的異步等效項之外別無其他。
在有問題的情況下,第二階段的存儲庫調用非異步版本,因此上面的代碼基本上是用.Wait()
調用的。
在上面的代碼之前,此HTTP請求中沒有其他異步調用,從它進入Web API的控制器。
錯誤幾乎肯定會進一步上升到你的調用堆棧,其中某些方法阻止返回的任務(例如, Task<T>.Result
Task.Wait
, Task.Wait
等)。 如果要完成任務需要阻塞線程,則會發生死鎖。
我在博客上詳細解釋了這種情況 ,但其主旨是:
await
將捕獲“上下文”並使用它來恢復async
方法。 SynchronizationContext
; 如果此代碼在UI線程中執行,則此“上下文”是UI SynchronizationContext
。 SynchronizationContext
和UI SynchronizationContext
只允許其中的一個線程。 因此,當調用代碼阻塞返回的Task
,它在該上下文中保持一個線程,阻止Task
完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.