为什么 ConfigureAwait(true) 不适用于单元测试



默认情况下,单元测试不会捕获运行它的SynchronizationContext,因此如果您编写类似以下内容的内容:

[TestMethod]
public async Task AwaitThreadSwitch()
{
    WriteThread();
    await Do();
    WriteThread();
}
private Task Do()
{
    return Task.Run(() =>
    {
        WriteThread();
        Thread.Sleep(50);
    });
}
private void WriteThread()
{
    Debug.WriteLine($"CURRENT THREAD: {Thread.CurrentThread.ManagedThreadId}");
}

您将获得以下输出:

CURRENT THREAD: 8
CURRENT THREAD: 6
CURRENT THREAD: 6

没关系:一旦调用并返回await,流就不会返回到原始线程。

现在,如果我这样编写测试方法:

[TestMethod]
public async Task AwaitThreadSwitch()
{
    WriteThread();
    await Do().ConfigureAwait(true);  // <-- note this change
    WriteThread();
}

我期望:

CURRENT THREAD: 8
CURRENT THREAD: 6
CURRENT THREAD: 8 // <-- back to the main Thread

相反,我得到了第一次测试的相同结果。

为什么执行没有编组回测试方法的主线程?

您似乎误解了为什么测试没有在第一个例子中封送回主线程。这不是因为某处的某些东西隐含地设置了ConfigureAwait(false).相反,这是因为没有同步上下文

您的两个测试实际上是相同的。调用ConfigureAwait(true)与根本不调用它没有什么不同。只是没有上下文可以返回,默认的同步上下文行为是在同一线程中继续。

所以,这就是你在两个测试中看到的。因为两个测试确实做同样的事情。

最新更新