WebClient.DownloadStringTaskAsync在没有等待的情况下无法正常工作

时间:2015-04-20 21:03:36

标签: c# wpf async-await task

我有一个简单的wpf应用程序,只有一个按钮和一个文本块。按钮单击事件处理程序运行下一个代码:

var resultTask = webClient.DownloadStringTaskAsync("http://google.com");
textBlock.Text = resultTask.Result;

在我使用await

之前,这不起作用(它是视频群聊)
var result = await ebClient.DownloadStringTaskAsync("http://google.com");
textBlock.Text = result;

但是在简单的控制台应用程序中,它可以正常工作。

var resultTask = webClient.DownloadStringTaskAsync("http://google.com");
Console.WriteLine(resultTask.Result);

你能解释一下为什么第一个变体在wpf中不起作用吗?

2 个答案:

答案 0 :(得分:7)

这是sync-contexts常见的问题;基本上,.Result在UI线程可用之前无法获取同步上下文,并且在.Result完成(或失败)之前UI线程将不可用。基本上,您已经陷入僵局,这就是为什么您不应该使用.Wait().Result,除非您知道同步上下文是安全的 - 只需await

它在控制台应用程序中工作,因为没有同步上下文:可以在池线程上标记完成继续。在WPF中,sync-context将工作推送到UI线程,由于死锁而无法做到这一点。

一个hacky修复方法是在.ConfigureAwait(false)方法之后添加*Async

var resultTask = webClient.DownloadStringTaskAsync("http://google.com")
    .ConfigureAwait(false); 

但是这可以解决所有错误的原因,应该避免。使用await或使用同步调用。不要“同步异步” - 这是一个非常糟糕的主意。

答案 1 :(得分:0)

看起来你在UI事件线程上遇到了死锁。以下问题的接受答案更详细地解释了它:

Deadlock while blocking async HttpClient call within a task continuation