Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async / await vs BeginRead, EndRead

I don't quite 'get' async and await yet, and I'm looking for some clarification around a particular problem I'm about to solve. Basically, I need to write some code that'll handle a TCP connection. It'll essentially just receive data and process it until the connection is closed.

I'd normally write this code using the NetworkStream BeginRead and EndRead pattern, but since the async / await pattern is much cleaner, I'm tempted to use that instead. However, since I admittedly don't fully understand exactly what is involved in these, I'm a little wary of the consequences. Will one use more resources than the other; will one use a thread where another would use IOCP, etc.

Convoluted example time. These two do the same thing - count the bytes in a stream:

class StreamCount
{
    private Stream str;
    private int total = 0;
    private byte[] buffer = new byte[1000];

    public Task<int> CountBytes(Stream str)
    {
        this.str = str;

        var tcs = new TaskCompletionSource<int>();
        Action onComplete = () => tcs.SetResult(total);
        str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, onComplete);

        return tcs.Task;
    }

    private void BeginReadCallback(IAsyncResult ar)
    {
        var bytesRead = str.EndRead(ar);
        if (bytesRead == 0)
        {
            ((Action)ar.AsyncState)();
        }
        else
        {
            total += bytesRead;
            str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, ar.AsyncState);
        }
    }
}

... And...

    public static async Task<int> CountBytes(Stream str)
    {
        var buffer = new byte[1000];
        var total = 0;
        while (true)
        {
            int bytesRead = await str.ReadAsync(buffer, 0, 1000);
            if (bytesRead == 0)
            {
                break;
            }
            total += bytesRead;
        }
        return total;
    }

To my eyes, the async way looks cleaner, but there is that 'while (true)' loop that my uneducated brain tells me is going to use an extra thread, more resources, and therefore won't scale as well as the other one. But I'm fairly sure that is wrong. Are these doing the same thing in the same way?

like image 839
Barguast Avatar asked Oct 30 '14 11:10

Barguast


People also ask

Does async await improve performance?

C# Language Async-Await Async/await will only improve performance if it allows the machine to do additional work.

Is async await same as synchronous?

Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.

What is the advantages of async await approach?

The biggest advantage of using async and await is, it is very simple and the asynchronous method looks very similar to a normal synchronous methods. It does not change programming structure like the old models (APM and EAP) and the resultant asynchronous method look similar to synchronous methods.

Is async await parallel C#?

With TPL we can implement Parallel Programming in C# . NET very easy. Async and Await keywords were introduced in C# 5.0 by Microsoft. When you use the “Async” keyword, you can write code the same way you wrote synchronous code.


1 Answers

To my eyes, the async way looks cleaner, but there is that 'while (true)' loop that my uneducated brain tells me is going to use an extra thread, more resources, and therefore won't scale as well as the other one.

Nope, it won't. The loop will only use a thread when it's actually running code... just as it would in your BeginRead callback. The await expression will return control to whatever the calling code is, having registered a continuation which jumps back to the right place in the method (in an appropriate thread, based on the synchronization context) and then continues running until it either gets to the end of the method or hits another await expression. It's exactly what you want :)

It's worth learning more about how async/await works behind the scenes - you might want to start with the MSDN page on it, as a jumping off point.

like image 159
Jon Skeet Avatar answered Oct 16 '22 04:10

Jon Skeet