SimpleWorkItemDispatcher
SimpleWorkItemDispatcher handles execution of WorkItems by
directly executing them. It is provided so that a dispatcher
is always available in the context, thereby simplifying the
code needed to run child tests.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace NUnit.Framework.Internal.Execution
{
[NullableContext(1)]
[Nullable(0)]
public class SimpleWorkItemDispatcher : IWorkItemDispatcher
{
[Nullable(2)]
private WorkItem _topLevelWorkItem;
[Nullable(2)]
private Thread _runnerThread;
private readonly object _cancelLock = new object();
public int LevelOfParallelism => 0;
public void Start(WorkItem topLevelWorkItem)
{
_runnerThread = new Thread(RunnerThreadProc) {
Name = "NUnit.Fw.SimpleWorkItem"
};
if (topLevelWorkItem.TargetApartment != ApartmentState.Unknown) {
if (OperatingSystem.IsWindows())
_runnerThread.SetApartmentState(topLevelWorkItem.TargetApartment);
else
topLevelWorkItem.MarkNotRunnable("Apartment state cannot be set on this platform.");
}
_runnerThread.Start(topLevelWorkItem);
}
public void Dispatch(WorkItem work)
{
work?.Execute();
}
[NullableContext(2)]
private void RunnerThreadProc(object obj)
{
_topLevelWorkItem = (WorkItem)obj;
_topLevelWorkItem.Execute();
}
public void CancelRun(bool force)
{
lock (_cancelLock) {
if (_topLevelWorkItem != null) {
_topLevelWorkItem.Cancel(force);
if (force)
_topLevelWorkItem = null;
}
}
}
}
}