ToListAsync()未完成所有 [英] ToListAsync() does not complete at all
问题描述
我要执行一些查询异步。 但是,当我在code调试,大多数时候一个ToListAsync()被调用的程序停止。 没有可见的异常,并调用堆栈窗口被清除。 当我preSS在VS暂停按钮,我可以看到当前的方法被调用之前堆栈帧。
I want to execute some queries async. But when I debug through the code, most times when an ToListAsync() is called the program stops. There is no visible exception, and the callstack window is cleared. When I press the pause button in VS, I can see the stack frame just before the current method was called.
var res1 = await context.Address().Where(...).ToListAsync();
var res2 = await context.Person().Where(...).ToListAsync();
var res3 = await context.Rule().Where(...).ToListAsync();
有时候第一次调用工作,在极少数情况下,第二个了。 但是至少在第三调用的程序停止。 我绝对不知道为什么...
Sometimes the first call works, in rare cases the second too. But at least at the third call the program stops. I have absolutely no clue why...
推荐答案
从注释:
这是一个WPF应用程序。该命令是一个异步方法中。我用把这种从一个非异步方法 VAR的结果= LoadAsync.Result();
It is a wpf application. The commands are within an async method. I call this from a non-async method using
var result = LoadAsync.Result();
就在那里,那是一个僵局。该<一href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchersynchronizationcontext(v=vs.110).aspx"><$c$c>DispatcherSynchronizationContext$c$c>试图编组的延续(一切后,第一个计谋
)返回到调度器(UI)线程,这是目前被调用封杀 LoadAsync。结果
Right there, thats a deadlock. The DispatcherSynchronizationContext
tries to marshal the continuation (everything after the first await
) back onto the dispatcher (UI) thread, which is currently blocked by the call to LoadAsync.Result
解决方法:
-
等待
在你调用堆栈的顶部通过你的方法返回,而不是一个异步任务
使用Task.Result
:
await
at the top of your call stack by making your method return anasync Task
instead of usingTask.Result
:
await LoadAsync();
如果你绝对不能在堆栈的顶部异步任务改变方法
对于一些模糊的原因有还叫 Task.Result
,使用<一个href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.configureawait(v=vs.110).aspx"><$c$c>ConfigureAwait(false)$c$c> awating你内心的异步方法时。这将告诉同步上下文明确不尝试元帅的工作回调度线程:
If you absolutely cant change the method at the top of of the stack to async Task
and for some obscure reason have to still call Task.Result
, use ConfigureAwait(false)
when awating your inner async methods. This will tell the sync context to explicitly not attempt to marshal work back to the dispatcher thread:
var res1 = await context.Address().Where(...).ToListAsync().ConfigureAwait(false);
var res2 = await context.Person().Where(...).ToListAsync().ConfigureAwait(false);
var res3 = await context.Rule().Where(...).ToListAsync().ConfigureAwait(false);
这篇关于ToListAsync()未完成所有的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!