I'm aware that there are several similar questions on this and other websites, but the standard way of doing this doesn't appear to work in my situation for some reason. The normal way to accomplish this requirement is to use TaskScheduler.FromCurrentSynchronizationContext()
as the TaskScheduler
input parameter in the relevant Task.Factory.StartNew
overload:
// Set uiTaskScheduler whilst on the UI thread
TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
...
Task.Factory.StartNew(() => SomeMethodToRunAsynchronously(),
CancellationToken.None, TaskCreationOptions.None, uiTaskScheduler);
It appears that this is enough to schedule a Task
to run on the UI thread, but it doesn't seem to work in my situation. In my case, I have a UiThreadManager
class which among other things has a RunAsynchronously
method in it:
public Task RunAsynchronously(Action method)
{
return Task.Run(method);
}
This part works just fine. The problem that I face is that when running unit tests, this class is replaced with a MockUiThreadManager
class (both implement an IUiThreadManager
interface which is used by the application code) and I can't seem to force this method to run on the UI thread:
public Task RunAsynchronously(Action method)
{
return Task.Factory.StartNew(() => method(),
CancellationToken.None, TaskCreationOptions.None, UiTaskScheduler);
}
The MockUiThreadManager
class has a static UiTaskScheduler
property which is set (like below) on the UI thread, so I assumed that all code passing through the above method would run as expected on that thread:
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
MockUiThreadManager.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
However, when running a unit test, I noticed that it finished before the code that it was testing. I therefore added some breakpoints and called System.Threading.Thread.CurrentThread.ManagedThreadId
in the Visual Studio Immediate Window at each breakpoint and sure enough, when the code passed through the above method, the thread ID changed.
So basically, I'm looking for a way to fake a Task
based asynchronous call for the RunAsynchronously
method that is run during unit tests that will ensure that the method actually runs synchronously on the UI thread. Does anybody see what I have done wrong, or have any other suggestions?
Aucun commentaire:
Enregistrer un commentaire