3

I've been looking for any simple example building async interfaces using ASP.NET WebForms. That is when an async method is done the await shall render.

This is one of the examples I've been looking at, How and When to use `async` and `await`. The implementation I've been looking for would look something like this

protected async void button1_Click(object sender, EventArgs e)
{
    // Render when done
    textBox1.Text += await WaitAsynchronouslyAsync(RandomNumber(2000, 4000));

    // Render when done
    textBox1.Text += await WaitAsynchronouslyAsync(RandomNumber(100, 1000));
}

public async Task<string> WaitAsynchronouslyAsync(int delay)
{
    await Task.Delay(delay);
    return string.Concat(delay, "; ");
}
private int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

This will however always render when everything is done, but at the same time. In the example above the desired result would be the second call to WaitAsynchronouslyAsync to render before the first call since it always will be less delay.

Or is it even possible using webforms? I do know how to do this in JavaScript using webapi's, websockets and whatnot and that's not the solution I desire at the moment.

Community
  • 1
  • 1
Eric Herlitz
  • 25,354
  • 27
  • 113
  • 157

2 Answers2

2

As I describe on my blog, async does not change the HTTP protocol.

HTTP provides you with one response for each request. So, when an HTTP request arrives, it must execute your page to completion before sending the response.

In the ASP.NET world, await does not yield to the client/browser. Instead, it yields to the ASP.NET runtime. ASP.NET will not send the response until it sees that your processing is all done.

If you want to dynamically update a page (or partially render one), then you'll need to do it yourself using an appropriate technology (SignalR, UpdatePanel, etc).

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Ah, figures. I was hoping there were some library I could use that simplifies the handling of this. But since the methods and their implementation is async (and will run to the bitter end) all I need is a state changing mechanism that will update the page whenever the status of the methods have changed I suppose. – Eric Herlitz Oct 19 '14 at 07:23
1

When you use await in the manner that you did, execution flow is sequential. The first await, and only after it finishes will the second await execute.

If you want them executed concurrently, you can initiate both operations and use Task.WhenAny and assign the value of whichever task finishes first:

Task<string> slowerTask = WaitAsynchronouslyAsync(RandomNumber(2000, 4000));
Task<string> fasterTask = WaitAsynchronouslyAsync(RandomNumber(100, 1000));

List<Task<string>> tasks = new List<Task<string>> { slowerTask, fasterTask };

while (tasks.Count > 0)
{
     Task<string> finishedTask = await Task.WhenAny(tasks);
     tasks.Remove(finishedTask);

     textBox1.Text = await finishedTask;
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321