等待的奇怪行为

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);
}