首先是一小部分背景信息.我正在使现有的C#库代码适合在WinRT上执行.作为这段代码的一小部分内心深处需要做一个小文件IO,我们首先尝试保持同步并使用Task.Wait()来停止主线程直到所有IO完成.
果然,我们很快发现导致陷入僵局.
然后我发现自己在原型中改变了很多代码,使其"异步".也就是说,我插入了异步和等待关键字,我正在相应地更改方法返回类型.这是一项很多工作 - 实际上是太多无意义的工作 - 但是我以这种方式工作了原型.
然后我做了一个实验,我在一个单独的线程上使用Wait语句运行原始代码:
System.Threading.Tasks.Task.Run(()=> Draw(..., cancellationToken)
Run Code Online (Sandbox Code Playgroud)
没有死锁!
现在我很困惑,因为我认为我理解异步编程是如何工作的.我们的代码(还)根本没有使用ConfigureAwait(false).因此,所有等待语句应该在调用它们的相同上下文中继续.对吧?我认为这意味着:同一个线程.现在,如果此线程调用了"Wait",这也会导致死锁.但事实并非如此.
你们中有谁有明确的坚如磐石的解释吗?
这个问题的答案将决定我是否真的会通过插入大量有条件的async/await关键字来搞乱我们的代码,或者我是否会保持它干净并只使用一个在这里和那里执行Wait()的线程.如果延续由任意非阻塞线程运行,那么事情应该没问题.但是,如果它们由UI线程运行,如果延续计算成本很高,我们可能会遇到麻烦.
我希望这个问题很清楚.如果没有,请告诉我.