How do I use the Async Await functions in C# correctly

I'm still having trouble understanding how to use Async methods. I have the following code in a controller.

[HttpPost]
public async Task<IActionResult> ManualUpload([Bind("MktRpt")] ManualMktRptFileUpload itemFileUpload)
{
    var manager = new RecyclableMemoryStreamManager();
    using (var stream = manager.GetStream())
    {
       await itemFileUpload.MktRpt.CopyToAsync(stream);
       await _azureStorageService.saveBlob(stream, Path.GetFileName(itemFileUpload.MktRpt.FileName));
    }

    itemFileUpload.status = "Success";
    return View(itemFileUpload);
}

my service method is simple too:

public async Task saveBlob(MemoryStream stream, string filename)
{
    var blockBlob = _container.GetBlockBlobReference(filename);
    await blockBlob.UploadFromStreamAsync(stream);
}

along with a simple model class:

public class ManualMktRptFileUpload
{
    [Required]
    [Display(Name = "Manual Report")]
    public IFormFile MktRpt { get; set; }

    public string status { get; set; } = "Constructed";
}

When I check my Blob Container in Azure, the file is there BUT, it's zero bytes.

I believe this is because I am not correctly waiting for the stream to transfer, but I don't know how to fix it.

Jon Skeet
people
quotationmark

I doubt that this has anything to do with async really. Currently you're copying one stream into a MemoryStream, but then leaving the "cursor" at the end of the MemoryStream... anything trying to read from it won't see the new data.

The fix is really simple: just "rewind" the stream before you call your saveBlob method:

using (var stream = manager.GetStream())
{
   await itemFileUpload.MktRpt.CopyToAsync(stream);
   stream.Position = 0;
   await _azureStorageService.saveBlob(stream, Path.GetFileName(itemFileUpload.MktRpt.FileName));
}

Alternatively, avoid the copying into the MemoryStream entirely:

using (var stream = itemFileUpload.MktRpt.OpenReadStream())
{
    await _azureStorageService.saveBlob(stream, Path.GetFileName(itemFileUpload.MktRpt.FileName));
}

people

See more on this question at Stackoverflow