没有等待,WebClient.DownloadStringTaskAsync不起作用

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中不起作用吗?

Mar*_*ell 7

这是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或使用同步调用.不要"同步异步" - 这是一个非常糟糕的主意.