I'm trying to use the async methods to upload a file to Azure blob storage and then set its metadata, but the UploadFromByteArrayAsync
method never returns.
I have the following code:
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;
}
Using the above code, I'd expect to see the following messages logged:
SaveToBlobAsync: blob 123 uploaded.
SaveToBlobAsync: 123 - metadata saved.
But these never appear.
However, the blob does appear to be stored (I can view its contents using the Azure Storage Explorer) but the process doesn't seem to move to the next line (which would be the first logging message).
If I switch all the async calls for their non-async counterparts then the code works as expected.
Can anyone explain why UploadFromByteArrayAsync
doesn't seem to return?
Update: I thought I'd add some more information about the context, in case it helps.
This code is being called from a Web API method. The controller in question has no async code and does little else other than call a repository method. The repository method updates a SQL DB - again, all this is non-async code - before calling a class which interfaces with the blob storage.
This blob storage-facing class has non-async methods which do little else other than calling their async equivalents with either .Wait()
or .Result
.
In the case in question, the repository in the second stage is calling the non-async version, so the above code is essentially being called with .Wait()
.
Until the above code, there are no other async calls in this HTTP request from the point where it enters the Web API's controller.