Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么ConfigureAwait(true)在单元测试上不起作用?_C#_Multithreading_Unit Testing_Synchronizationcontext - Fatal编程技术网

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