2

I am uploading a file asynchronously to Azure blob storage using a standard function, however the only method I have available to use, uses a delegate to pass control to a second function. But I need a return value from the first function (preferably using await).

How can I await the result and therefore return the value in the first function? Can I await the delegate function? I want to return blob.uri

Here's the code:

      private Uri uploadImageFileToContainer(byte[] fileContent, string containerName, string blobName)
    {
        CloudBlobClient blobClient = myAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference(containerName);
        container.CreateIfNotExist();
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);

        // see: http://www.c-sharpcorner.com/UploadFile/40e97e/windows-azure-blockblob-putblock-method/ for details            

        HashSet<string> blocklist = new HashSet<string>();
        foreach (FileBlock block in GetFileBlocks(fileContent))
        {
            blockBlob.PutBlock(
                block.Id,
                new MemoryStream(block.Content, true),
                null
                );
            blocklist.Add(block.Id);
        }
         **AsyncCallback UploadCompleted = new AsyncCallback(OnUploadCompleted);
         blockBlob.BeginPutBlockList(blocklist, OnUploadCompleted, blockBlob);**


    }

    private void   OnUploadCompleted(IAsyncResult result)
    {
        CloudBlockBlob blob = (CloudBlockBlob)result.AsyncState;
        blob.SetMetadata();
        blob.EndPutBlockList(result );
    }
WaterBoy
  • 697
  • 3
  • 13
  • 35
  • 3
    For `BeginXXX/EndXXX` APM callback pattern, you can use `Task.Factory.FromAsync` and `await` the task it returns, [example](http://stackoverflow.com/a/21498956/1768303). – noseratio Aug 19 '14 at 22:45

3 Answers3

4

In the latest versions of Azure Storage Client Library, all APIs have a corresponding Async overload that returns a Task. For example, please refer to CloudBlockBlob.PutBlockListAsync.

Serdar Ozler
  • 3,752
  • 17
  • 24
2

For all async/await methods, you need to begin by making your method async and returning a Task. Then use FromAsync to wrap the old async pattern in a Task. Something like this ought to work.

private async Task<Uri> uploadImageFileToContainer(byte[] fileContent, string containerName, string blobName)
{ 
    ...
    await Task.Factory.FromAsync<IEnumerable<string>>(
        blockBlob.BeginPutBlockList, blockBlob.EndPutBlockList, blockList, blockBlob);
    blob.SetMetadata();
    return blob.Uri;
}
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
1

I'm using WindowsAzure.Storager version 4.2.1

Instead of:

AsyncCallback UploadCompleted = new AsyncCallback(OnUploadCompleted);
blockBlob.BeginPutBlockList(blocklist, OnUploadCompleted, blockBlob);

I can:

await blockBlob.PutBlockListAsync(blocklist);
blockBlob.SetMetadata();
blockBlob.EndPutBlockList(result);
spender
  • 117,338
  • 33
  • 229
  • 351