[英]Behavior async await console application vs. WPF
我是异步等待的新手。 我想我了解控制台应用程序的示例。 将相同的代码传输到WPF时,会出现死锁,我也不知道为什么。
// All as expected
// Output:
// LongOperationAsync Start
// Before task.Wait();
// LongOperationAsync End
// After task.Wait();
// Result: 4711
class Program {
public static void Main() {
Task<int> task = LongOperationAsync();
//Console.ReadKey();
Console.WriteLine("Before task.Wait();");
task.Wait();
Console.WriteLine("After task.Wait();");
var result = task.Result;
Console.WriteLine("Result: {0}", result);
Console.ReadKey();
}
static async Task<int> LongOperationAsync() {
Console.WriteLine("LongOperationAsync Start");
await Task.Delay(1000);
Console.WriteLine("LongOperationAsync End");
return 4711;
}
}
这是阻塞的WPF代码:
// WPF handler Output:
// LongOperationAsync Start
// Before task.Wait(); => Blocking
private void button2_Click(object sender, EventArgs e) {
Task<int> task = LongOperationAsync();
Debug.WriteLine("Before task.Wait();");
task.Wait();
Debug.WriteLine("After task.Wait();");
var result = task.Result;
Debug.WriteLine("Result: {0}", result);
}
private async Task<int> LongOperationAsync() {
Debug.WriteLine("LongOperationAsync Start");
await Task.Delay(1000);
Debug.WriteLine("LongOperationAsync End");
return 4711;
}
两种情况下的代码块。 这两个例子都是不好的。 两者都不异步执行。
正确的控制台代码为:
public static async Task Main()
{
Console.WriteLine("Before LongOperationAsync");
int result = await LongOperationAsync();
Console.WriteLine("After LongOperationAsync");
Console.WriteLine("Result: {0}", result);
Console.ReadKey();
}
等效的WPF代码为:
private async void button2_Click(object sender, EventArgs e)
{
Debug.WriteLine("Before LongOperationAsync");
int result = await LongOperationAsync();
Debug.WriteLine("After LongOperationAsync");
Debug.WriteLine("Result: {0}", result);
}
async
是语法糖,它允许使用await
关键字。 await
异步等待已完成的异步操作(如Task.Delay()
完成,而不会阻塞原始线程。 该异步操作完成后, await
在原始同步上下文中恢复执行。 在WPF应用程序的情况下,这就是UI线程。 这就是允许在await
之后更新UI的原因。
async void
仅适用于事件处理程序,例如button2_click
。 在所有其他情况下,应使用async Task
。 不能等待async void
方法,应用程序也不知道它们是否完成。
在您的示例中,您可以将按钮单击修改为异步。 您的任务被阻止,因为您从不启动他,如果不启动任务,您将永远无法通过“ wait()”调用。
在修改后的按钮单击方法下面。
private async void button2_Click(object sender, EventArgs e)
{
var result = await LongOperationAsync();
Debug.WriteLine("Result: {0}", result);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.