Given the following code:
public static async void CurrentThreadCall()
{
Console.WriteLine("Begin on thread {0}", Thread.CurrentThread.ManagedThreadId);
await BackgroundCall();
Console.WriteLine("Completed on thread {0}", Thread.CurrentThread.ManagedThreadId);
}
private static async Task BackgroundCall()
{
await Task
.Run(() =>
{
Console.WriteLine("Task run on thread: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromMilliseconds(100));
})
.ConfigureAwait(false);
}
Calling the CurrentThreadCall() method from a WPF application, the Begin and Completed outputs will run on the same threads (just as I would expect):
BackgroundCall begin: 9
Task run on thread: 6
Completed on thread 9 <--- As expected
If I call the method from a unit test and use the ReSharper testrunner (2016.2 in VS2015), the Completed output will instead run on the same thread as the task:
Begin on thread 11
Task run on thread: 4
Completed on thread 4 <-- Not what I expected
Why is this, and can I do something in my test to make it work like in the WPF application?
What I have tried...
I have tried to make the test method async:
[Test]
public async Task MyTest()
{
await CurrentThreadCall();
}
In desperation, I have tried to set the SynchronizationContext from the test:
[Test]
public void MyTest()
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
CurrentThreadCall();
}
...with no luck.
Task continuations after await run on the same synchronization context, not on the same thread. For WPF applications, the synchronization context is associated with the dispatcher, and there is only one dispatcher thread. Hence continuations run on the same thread. In unit tests there either no synchronization context or as in your example, it is default sync context associated with the thread pool. Thus, continuation may run on any of the threads in the thread pool.
If you want to reproduce the behavior exactly in tests, you should use one of single-threaded synchronization contexts - the DispatcherSynchronizationContext or e.g. https://github.com/StephenCleary/AsyncEx/wiki/AsyncContext
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With