Aysnc Read Challenge

time to read 3 min | 450 words

Originally posted at 11/11/2010

Here is how you are supposed to read from a stream:

var buffer = new byte[bufferSize];
int read = -1;
int start = 0;
while(read != 0)
{
   read = stream.Read(buffer, start, buffer.Length - start);
   start += read;
}

The reason that we do it this way is that the stream might not have all the data available for us, and might break the read requests midway.

The question is how to do this in an asynchronous manner. Asynchronous loops are… tough, to say the least. Mostly because you have to handle the state explicitly.

Here is how you can do this using the new Async CTP in C# 5.0:

private async static Task<Tuple<byte[], int>> ReadBuffer(Stream s, int bufferSize)
{
    var buffer = new byte[bufferSize];
    int read = -1;
    int start = 0;
    while (read != 0)
    {
        read = await Task.Factory.FromAsync<byte[],int,int, int>(
            s.BeginRead, 
            s.EndRead, 
            buffer, 
            start, 
            buffer.Length -1, 
            null);
        start += read;
    }
    return Tuple.Create(buffer, start);
}

Now, what I want to see is using just the TPL API, and without C# 5.0 features, can you write the same thing?