Hem*_*era 6 c# asynchronous task-parallel-library async-await
我有一个定义为的方法
public async Task SomeAsyncMethod()
{
DoSomeStuff();
await Task.Run(() => {
DoSomeSyncStuff();
DoSomeOtherSyncStuff();
});
var someDebugVariable = "someDebugValue";
}
Run Code Online (Sandbox Code Playgroud)
该方法本身正是它应该做的事情,一切运行正常.然而......看起来"外部"异步Task从未完成.
示例:当我这样称呼它时
public void CallerMethod()
{
Task t = SomeAsyncMethod();
t.Wait();
}
Run Code Online (Sandbox Code Playgroud)
将t.Wait()永远不会完成.此外:如果我在分配时放置一个断点,someDebugVariable它永远不会被击中.
我可能会添加它DoSomeSyncStuff并且DoSomeOtherSyncStuff真正做他们应该做的事情并通过它们调试告诉我他们都完成了.
为了证明我的观点,我修改了这样的方法,结果仍然是一样的.
public async Task SomeAsyncMethod()
{
DoSomeStuff();
await Task.Run(() => {
/*
DoSomeSyncStuff();
DoSomeOtherSyncStuff();
*/
var a = 2; var b = 3; var c = a + b;
});
var someDebugVariable = "someDebugValue";
}
Run Code Online (Sandbox Code Playgroud)
编辑
我已经尝试删除除了await Task.Run它之外的一切,它不会改变任何东西.它仍然没有完成.
该应用程序是一个WPF应用程序.调用者线程是UI线程.
我在这里错过了什么?
Ste*_*eve 10
t.Wait()调用导致死锁,并使异步调用完全没有意义.我相信如果你改变代码
await Task.Run(() => {
// ...
}).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
您可以修复死锁并让代码继续,但您应该真正摆脱t.Wait()调用.任何需要使用sync函数调用结果完成的操作都应在等待任务之后完成,而不是在调用异步函数之后完成.
更深入:task.Wait()将在任务运行时阻止主线程上的所有执行.当await任务完成时,它会尝试编组回主线程,但主线程被阻塞了!由于A正在等待B,并且B正在等待A,因此会出现死锁.
请参阅:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
| 归档时间: |
|
| 查看次数: |
1995 次 |
| 最近记录: |