sinni800
sinni800

Reputation: 1449

Intermediate results in the new Async/Await commands

I have been wondering...

Do the new Async constructs actually allow for intermediate results without writing new code on the consumer side?

Let me elaborate with an example.

Let's say we have a method that downloads data into a byte array or a stream, whichever is better.

Is it possible, that a method that awaits said method can start consuming the byte array or stream before the download is complete with the built in async features? What I could do is raise events everytime a certain part of the stream is downloaded, but that increases clutter again.

Let me write a code example (from the top of my head, will not be correct code!) that I (would) expect to result in intermediate results, given the awaited method returns such results.

io.Stream data = await downloadData();
byte[4096] buffer = new byte[4096];
while (!data.EOF) {
  (await?) data.Read(buffer, offset, 4096);
}

As of now, Stream.Read is not awaitable, do we have any method of doing this, though? I want to be able to await through a transfer. Am I overseeing anything?

Upvotes: 1

Views: 2381

Answers (2)

James Manning
James Manning

Reputation: 13579

I'm not really familiar enough with it to give you a good example, but since it sounds like you don't want a one-time result, but instead multiple results, that sounds like a better fit for observable. Thenter link description hereis image from the Rx team's 2.0 beta blog post is extremely useful along those lines (IMHO).

enter image description here

Upvotes: 2

svick
svick

Reputation: 244868

If you're using Stream in .Net 4.5, you can use its ReadAsync() method for this:

Stream stream = await downloadData();
byte[4096] buffer = new byte[4096];
int read;
do
{
    read = await stream.ReadAsync(buffer, 0, buffer.Length);
    // do something with buffer here
} while (read > 0);

If you mean that your stream does not have a method such as ReadAsync(), but does support asynchrony using the BeginXxx(), EndXxx() pattern, and you want to use await, then you can do that too:

do
{
    read = await Task.Factory.FromAsync<byte[], int, int, int>(
        stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null);
    // do something with buffer here
} while (read > 0);

But, if you only have a synchronous Read() method, the only way to use it with async would be to start a new Task on a background thread:

do
{
    read = await Task.Run(() => stream.Read(buffer, 0, buffer.Length));
    // do something with buffer here
} while (read > 0);

The problem with this code is that it still blocks a thread, which is what async is trying to avoid. But it might still be useful if the method runs on a GUI thread, and you can't run the whole loop on a background thread.

Upvotes: 2

Related Questions