等待的奇怪行为
Strange behavior of await
我有一个像这样的异步方法
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
实际上没有任何用处,这让我很震惊。
您的 FooAsync()
尽管名称如此,但实际上是在同步进行工作,因此由于您是在 UI 线程上开始工作,它将继续在UI 线程。
当您在 ContinueWith
中添加时,您会在线程池线程上强制一个方法(没有任何生产性)到 运行,因此只有第一个 FooAsync
调用是实际上 运行ning 在 UI 线程上。由于 ConfigureAwait(false)
.
,所有后续调用都将在线程池线程上进行
正确的 修复是实际调整 FooAsync
以便它实际上异步而不是同步地完成它的工作,或者如果它不做任何概念上的异步工作,那么它应该是一个 synchronous 方法,而不是 return 一个 Task
,并且在你的方法中用 Task.Run
调用,因为它需要在另一个线程中完成同步工作。
答案在你的问题中,发生了什么事向你解释 Servy jet - 只需从线程池开始:
for (var i = 0; i < 10; i++)
{
ok &= await Task.Run(() => { return FooAsync(); }).ConfigureAwait(false);
}
我有一个像这样的异步方法
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
实际上没有任何用处,这让我很震惊。
您的 FooAsync()
尽管名称如此,但实际上是在同步进行工作,因此由于您是在 UI 线程上开始工作,它将继续在UI 线程。
当您在 ContinueWith
中添加时,您会在线程池线程上强制一个方法(没有任何生产性)到 运行,因此只有第一个 FooAsync
调用是实际上 运行ning 在 UI 线程上。由于 ConfigureAwait(false)
.
正确的 修复是实际调整 FooAsync
以便它实际上异步而不是同步地完成它的工作,或者如果它不做任何概念上的异步工作,那么它应该是一个 synchronous 方法,而不是 return 一个 Task
,并且在你的方法中用 Task.Run
调用,因为它需要在另一个线程中完成同步工作。
答案在你的问题中,发生了什么事向你解释 Servy jet - 只需从线程池开始:
for (var i = 0; i < 10; i++)
{
ok &= await Task.Run(() => { return FooAsync(); }).ConfigureAwait(false);
}