我试图获得一个web页面的异步源,实际上这是我以前做过几千次的事情。 当它不是异步的时候它是工作的,但是每当我试图使它异步的时候它就冻结了。
我试过:
await new WebClient().DownloadStringAsyncTask();
使用内部的WebRequest
await Task.Run(() => {
});
在内部使用new WebClient().DownloadString()
await Task.Run(() => {
});
使用HttpClient.GetAsync();
他们都失败了。 当我跟踪task.run()
内部时,我注意到操作实际上是工作的,得到结果并完成,但是完成后它永远不会返回。 我甚至使用空task.run()进行了测试,如下所示:
await Task.Run(() =>{
});
但它还是没有回来? 是。NET Framework 4.8中的一个bug吗? 为什么一个我用了上千次的简单代码会停止工作?
顺便说一下,它是一个Winforms应用程序。
调用此异步代码的代码在此任务完成时被阻塞(通过.result
或.wait()
)。 Winforms任务计划程序假设您的任务需要在它开始时所在的同一个线程上继续,但该线程正在等待您的任务完成,从而使您处于死锁状态。
一个解决方案是在调用堆栈中向上移除阻塞代码,然后“一路异步”。 (听起来这需要重构构造函数中的异步逻辑,无论如何,我强烈建议这样做)。
另一种方法是在所有await
之前始终如一地使用.configureAwait(false)
,这些await
不需要在它们开始的同一个线程上继续。
另一种方法是将task.run(。。。)
调用放入阻塞的代码部分,这样它就会显式地阻塞在另一个线程上。