sep*_*lka 0 c# wpf task async-await
我有一个简单的wpf应用程序,只有一个按钮和一个文本块.按钮单击事件处理程序运行下一个代
var resultTask = webClient.DownloadStringTaskAsync("http://google.com");
textBlock.Text = resultTask.Result;
Run Code Online (Sandbox Code Playgroud)
在我使用await之前,这不起作用(它是挂起)
var result = await ebClient.DownloadStringTaskAsync("http://google.com");
textBlock.Text = result;
Run Code Online (Sandbox Code Playgroud)
但在简单的控制台应用程序中它工作正常
var resultTask = webClient.DownloadStringTaskAsync("http://google.com");
Console.WriteLine(resultTask.Result);
Run Code Online (Sandbox Code Playgroud)
你能解释一下为什么第一个变体在wpf中不起作用吗?
这是sync-contexts常见的问题; 基本上,在.ResultUI线程可用之前无法获取同步上下文,并且UI线程在.Result完成(或失败)之前将不可用.基本上,你已经陷入僵局,这就是为什么你不应该使用.Wait()或.Result除非你知道同步上下文是安全的 - 只是await.
它在控制台应用程序中工作,因为没有同步上下文:可以在池线程上标记完成继续.在WPF中,sync-context将工作推送到UI线程,由于死锁而无法做到这一点.
一个hacky修复方法是.ConfigureAwait(false)在*Async方法后添加:
var resultTask = webClient.DownloadStringTaskAsync("http://google.com")
.ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
但这可以解决所有错误的原因,应该避免.使用await或使用同步调用.不要"同步异步" - 这是一个非常糟糕的主意.