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

时间:2017-05-06 22:15:43

标签: c# multithreading unit-testing synchronizationcontext

默认情况下,单元测试不会捕获运行它的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

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

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

1 个答案:

答案 0 :(得分:3)

您似乎误解了为什么测试没有在第一个示例中编组回主线程。这不是因为某些地方隐含地设置了ConfigureAwait(false)。相反,它是因为没有同步上下文

你的两个测试实际上完全相同。拨打ConfigureAwait(true)与根本不打电话有所不同。它只是没有回复的上下文,默认的同步上下文行为只是在同一个线程中继续。

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