Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous memory streaming approach: which of the following?

I am working on solution which uses asynchronous memory streaming and I am thinking about right approach for implementing such. Which one is more convenient? The first, simple:

//First approach: linear async
private async static Task WriteToStreamFirstVariant()
{
    MemoryStream memoryStream = new MemoryStream();
    byte[] data = new byte[256];
    try
    {
        await memoryStream.WriteAsync(data, 0, data.Length);
    }
    catch(Exception exception)
    {
        //Handling exception
    }
    finally
    {
        memoryStream.Dispose();
    }
}

Or the second with nested tasks and closures?

//Second approach: nested tasks async
private async static Task WriteToStreamSecondVariant()
{
    await Task.Run(async () =>
    {
        byte[] data = new byte[256];
        using (MemoryStream memoryStream = new MemoryStream())
        {
            await memoryStream.WriteAsync(data, 0, data.Length)
                .ContinueWith((Task writingTask) =>
                {
                    //Handling exceptions
                    AggregateException exceptions = writingTask.Exception;
                });
        }
    }); 
}
like image 686
Ilya Tereschuk Avatar asked Dec 27 '13 17:12

Ilya Tereschuk


1 Answers

The fact is that MemoryStream's Read/WriteAsync methods don't actually provide any kind of true asynchronous implementation. All they do is perform the operation synchronously and return an already completed Task. Therefore there is no benefit to calling the async methods when you know it's a MemoryStream. In fact, it's just completely unnecessary overhead.

Now, forgetting that for a second just to answer your question on style, the first approach is better one because you don't allocate/schedule a new Task unnecessarily (e.g. with Task::Run), but I don't know why you wouldn't just use a using() statement in that approach. So here's the cleanest/simplest IMHO:

private async static Task WriteToStreamFirstVariantSimplified()
{
    using(MemoryStream memoryStream = new MemoryStream())
    {
        byte[] data = new byte[256];

        try
        {
            await memoryStream.WriteAsync(data, 0, data.Length);
        }
        catch(Exception exception)
        {
            //Handling exception
        }
   }
}
like image 66
Drew Marsh Avatar answered Sep 21 '22 22:09

Drew Marsh