0 c# wpf deadlock asynchronous async-await
我是异步等待的新手.我想我理解了控制台应用程序的例子.将相同的代码传输到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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是阻止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;
}
Run Code Online (Sandbox Code Playgroud)
两种情况下的代码都会阻塞.这两个例子都不好.都不是异步执行.
在正确的控制台代码如下:
public static async Task Main()
{
Console.WriteLine("Before LongOperationAsync");
int result = await LongOperationAsync();
Console.WriteLine("After LongOperationAsync");
Console.WriteLine("Result: {0}", result);
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
等效的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);
}
Run Code Online (Sandbox Code Playgroud)
async是语法糖,允许使用await关键字.异步await 等待已经Task.Delay()完成的异步操作,而不阻塞原始线程.当异步操作完成时,await继续在原始同步上下文中执行.在WPF应用程序的情况下,这是UI线程.这是允许在更新后更新UI的内容await.
async void仅适用于事件处理程序,例如button2_click.在所有其他情况下async Task应该使用.async void方法无法等待,应用程序无法知道它们是否已完成.
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |