使用WebForms和.NET 4.5 await/async实现异步GUI

3
我一直在寻找使用ASP.NET WebForms构建异步接口的简单示例。当一个 async 方法完成时, await 应该被呈现出来。
这是我一直在看的示例之一,如何和何时使用`async`和`await`。我正在寻找的实现将类似于此:
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);
}

然而,这将在所有工作完成时始终呈现,但同时。在上面的示例中,期望的结果是第二次调用WaitAsynchronouslyAsync比第一次调用更快呈现。

或者,使用WebForms是否可能实现这一点?我知道如何使用WebAPI、WebSockets等JavaScript来实现这一点,但那不是我目前想要的解决方案。

2个回答

2
正如我在我的博客上所描述的那样,async 不会改变 HTTP 协议
HTTP 为每个请求提供一个响应。因此,当一个 HTTP 请求到达时,它必须在发送响应之前完成执行您的页面。
在 ASP.NET 中,await 不会让客户端/浏览器暂停。相反,它会让 ASP.NET 运行时暂停。ASP.NET 只有在看到您的处理全部完成后才会发送响应。
如果您想动态更新页面(或部分渲染页面),则需要使用适当的技术(SignalR、UpdatePanel 等)自己完成。

啊,真是这样啊。我本来希望有一些库可以简化处理这个问题。但由于方法及其实现是异步的(并且将一直运行到最后),我想我只需要一个状态改变机制,每当方法的状态发生变化时就会更新页面。 - Eric Herlitz

1
当你以你所做的方式使用await时,执行流是顺序的。第一个await完成后才会执行第二个await
如果你想要它们同时执行,你可以启动两个操作并使用Task.WhenAny,并将完成的任务的值分配给它:
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;
}

@EricHerlitz 对不起,我当时在用手机。我已经编辑了我的代码。 - Yuval Itzchakov
它可以单向工作,下一步是找出是否有任何方法可以使Web控件异步。 - Eric Herlitz
方法仍在运行,即使我关闭了页面,但页面不会异步更新文本框。 - Eric Herlitz
我不太确定你的意思。 - Yuval Itzchakov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接