简体   繁体   中英

Why ConfigureAwait(true) does not work on unit tests?

By default, a unit test does not capture the SynchronizationContext in which it is run, so if you write something like:

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

You obtain the following output:

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

And that's ok: once the await is called and returns, the flow does not return to the original Thread.

Now, if I write the test method this way:

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

I would expect:

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

Instead, I get the same result of the first test.

Why isn't the execution marshalled back to the main Thread of the test method?

You seem to misunderstand why the test doesn't marshal back to the main thread in your first example. It's not because somewhere something has implicitly set ConfigureAwait(false) . Rather, it's because there is no synchronization context .

Your two tests are effectively identical. Calling ConfigureAwait(true) isn't different from not calling it at all. It's just that there's no context to come back to, and the default synchronization context behavior is to just continue on in the same thread.

So, that's what you see in both tests. Because both tests really do the same thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM