diff --git a/TUnit.Core/Executors/DedicatedThreadExecutor.cs b/TUnit.Core/Executors/DedicatedThreadExecutor.cs index ac9c3606e2..fa01ecf448 100644 --- a/TUnit.Core/Executors/DedicatedThreadExecutor.cs +++ b/TUnit.Core/Executors/DedicatedThreadExecutor.cs @@ -205,10 +205,10 @@ internal sealed class DedicatedThreadTaskScheduler : TaskScheduler { private readonly Thread _dedicatedThread; private readonly ManualResetEventSlim? _workAvailableEvent; + private readonly Lock _queueLock = new(); private readonly List _taskQueue = [ ]; - private readonly Lock _queueLock = new(); public DedicatedThreadTaskScheduler(Thread dedicatedThread, ManualResetEventSlim? workAvailableEvent) { @@ -296,10 +296,10 @@ public bool ProcessPendingTasks() internal sealed class DedicatedThreadSynchronizationContext : SynchronizationContext { + private Queue<(SendOrPostCallback callback, object? state)>? _workQueue = null; private readonly Thread _dedicatedThread; private readonly DedicatedThreadTaskScheduler _taskScheduler; private readonly ManualResetEventSlim? _workAvailableEvent; - private readonly Queue<(SendOrPostCallback callback, object? state)> _workQueue = new(); private readonly Lock _queueLock = new(); public DedicatedThreadSynchronizationContext(DedicatedThreadTaskScheduler taskScheduler, ManualResetEventSlim? workAvailableEvent) @@ -314,6 +314,7 @@ public override void Post(SendOrPostCallback d, object? state) // Always queue the work to ensure it runs on the dedicated thread lock (_queueLock) { + _workQueue ??= new(); _workQueue.Enqueue((d, state)); } // Signal that work is available (wake message pump immediately) @@ -384,7 +385,7 @@ public bool ProcessPendingWork() lock (_queueLock) { - if (_workQueue.Count == 0) + if (_workQueue == null || _workQueue.Count == 0) { break; }