I am not quite a 'get' async and am still waiting and I am looking for some clarification around the specific problem that I am going to solve. Basically, I need to write code that will handle the TCP connection. Essentially, it simply receives the data and processes it until the connection is closed.
I usually write this code using the NetworkStream BeginRead and EndRead patterns, but since the async / await pattern is much cleaner, I am tempted to use it. However, since I admittedly do not quite understand what is involved in them, I am a little afraid of the consequences. Will use more resources than another; whether a stream will be used in which another will use IOCP, etc.
Time for a minimized example. These two do the same - count the bytes in the 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; }
In my opinion, the asynchronous method looks cleaner, but there is a โwhile (true)โ loop that my uneducated brain tells me that it will use an extra thread, more resources and therefore will not scale, as well as another. But I'm sure this is wrong. Do they do the same thing?