我試圖使用異步方法將文件上載到Azure blob存儲,然後設置其元數據,但UploadFromByteArrayAsync
方法永遠不會返回。將異步上傳到Azure Blob存儲永遠不會返回
我有以下代碼:
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:團塊123上傳。
SaveToBlobAsync:123 - 保存元數據。
但是這些從不出現。
然而,blob似乎存儲(我可以使用Azure Storage Explorer查看其內容),但該進程似乎沒有移動到下一行(這將是第一個日誌消息)。
如果我切換所有的非異步對應的異步調用,則代碼按預期工作。
任何人都可以解釋爲什麼UploadFromByteArrayAsync
似乎不會返回?
更新: 我想我會添加一些關於上下文的更多信息,以防萬一它有幫助。
此代碼是從Web API方法調用的。有問題的控制器沒有異步代碼,除了調用存儲庫方法以外,沒有別的。在調用與blob存儲接口的類之前,存儲庫方法會更新SQL DB(再次,所有這些都是非異步代碼)。
該blob面向存儲的類具有非異步方法,除了調用與.Wait()
或.Result
之間的異步等效外,其他方法幾乎沒有任何其他功能。
在這種情況下,第二階段的存儲庫正在調用非異步版本,因此上述代碼實質上是使用.Wait()
調用的。
直到上面的代碼,這個HTTP請求中沒有其他的異步調用,從它進入Web API控制器的地方。
謝謝你的幫助,斯蒂芬,雖然我不知道這個阻塞可能發生在哪裏。我已經向OP中添加了更多信息,以便讓情況更加清晰。 – awj
@awj:你說過「在這種情況下,第二階段的存儲庫正在調用非異步版本,所以上述代碼基本上是使用.Wait()調用的。」 - 這是阻塞發生的地方。 –
你可能會解釋_why_我不能用'.Wait()'調用我的異步方法嗎?我在其他地方沒有問題地使用它,那麼爲什麼它會成爲一個問題呢? – awj