C# 为什么ConfigureAwait(true)在单元测试上不起作用?
默认情况下,单元测试不会捕获运行它的C# 为什么ConfigureAwait(true)在单元测试上不起作用?,c#,multithreading,unit-testing,synchronizationcontext,C#,Multithreading,Unit Testing,Synchronizationcontext,默认情况下,单元测试不会捕获运行它的SynchronizationContext,因此如果您编写以下内容: [TestMethod] public async Task AwaitThreadSwitch() { WriteThread(); await Do(); WriteThread(); } private Task Do() { return Task.Run(() => { WriteThread();
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
这没关系:一旦调用了wait
并返回,流就不会返回到原始线程
现在,如果我这样写测试方法:
[TestMethod]
public async Task AwaitThreadSwitch()
{
WriteThread();
await Do().ConfigureAwait(true); // <-- note this change
WriteThread();
}
[TestMethod]
公共异步任务线程开关()
{
WriteThread();
await Do().ConfigureAwait(true);//在第一个示例中,您似乎误解了为什么测试没有封送回主线程。这不是因为某个地方隐式设置了ConfigureAwait(false)
。而是因为没有同步上下文
您的两个测试实际上是相同的。调用ConfigureAwait(true)
与根本不调用它没有区别。只是没有上下文可返回,默认的同步上下文行为只是在同一线程中继续
这就是你在两个测试中看到的。因为这两个测试实际上做的是同一件事。ConfigureAwait
与线程无关。一点也不。池中的任何线程都可以执行任何任务。异步代码可以在任何线程上执行await
之后恢复。这是迄今为止对任务的一个误解代码>API。我不知道它从哪里来。@BenjaminHodgson:我不同意你的描述。确实,作为一个抽象,SynchronizationContext
不一定要与线程完全对应。但这并不意味着它实际上“什么都没有”在Winforms或WPF的常见情况下,上下文实际上与特定线程相关联,await
实际上将始终在该线程上恢复(除非另有指示),并且考虑代码在哪个线程上执行是非常有用的。可能是“误解”这是因为它实际上不是一个。但是如果我为我的单元测试设置了一个SynchronizationContext
,它们将不再相同,对吗?@MassimilianoKraus:不,你错了。你的单元测试实际上是相同的。即使你设置了SynchronizationContext
。要使它们不同,你必须调用ode>ConfigureAwait(false)
,而不是ConfigureAwait(true)
。
CURRENT THREAD: 8
CURRENT THREAD: 6
CURRENT THREAD: 8 // <-- back to the main Thread