我有一个像这样的异步方法
public async Task<bool> FooAsync()
{
return await SomeThirdPartyLib.SomeMethodReturningBoolAsync().ConfigureAwait(false);
}
然后我有一个代码在循环中调用它:
for (var i = 0; i < 10; i++)
{
ok &= await FooAsync().ConfigureAwait(false);
}
在我的情况下,这将在2或3或其他数量的周期后挂起我的过程。但是当我将代码更改为
时for (var i = 0; i < 10; i++)
{
ok &= await FooAsync()
.ContinueWith(t => {
if (t.IsCompleted)
{
return t.Result;
}
return false;
})
.ConfigureAwait(false);
}
完全相同的代码有效。有什么想法吗?
编辑:我刚刚更改了示例代码以显示FooAsync
原则上的内容。回复一些已经给出的答案和评论:我不确切知道SomeMethodReturningBoolAsync
的确切含义。我的ContinueWith
实际上没有任何用处,这一事实让我感到震惊。
答案 0 :(得分:6)
你的FooAsync()
尽管有名字,实际上是在同步进行工作,所以既然你在UI线程上开始工作,它将继续在UI线程上完成所有工作。 / p>
当您添加ContinueWith
时,您强制在线程池线程上运行一个方法(无效),因此只有第一个FooAsync
调用实际上正在运行UI线程。由于ConfigureAwait(false)
,所有后续调用都将位于线程池线程上。
正确的修复是实际调整FooAsync
,以便它实际上异步地工作,而不是同步,或者如果它没有做任何概念上的异步工作,那么它应该是同步方法,不返回Task
,并且在此方法中使用Task.Run
调用,因为它需要在另一个线程中执行同步工作。 / p>
答案 1 :(得分:0)
答案在你的问题里面,发生了什么事情解释你Servy jet - 刚开始在线程池中:
for (var i = 0; i < 10; i++)
{
ok &= await Task.Run(() => { return FooAsync(); }).ConfigureAwait(false);
}