diff --git a/src/Build/BackEnd/Components/Logging/LoggingService.cs b/src/Build/BackEnd/Components/Logging/LoggingService.cs index cfc289ad30e..be9ebe30f17 100644 --- a/src/Build/BackEnd/Components/Logging/LoggingService.cs +++ b/src/Build/BackEnd/Components/Logging/LoggingService.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -10,12 +10,12 @@ using System.Threading; using Microsoft.Build.BackEnd.Components.RequestBuilder; using Microsoft.Build.Evaluation; +using Microsoft.Build.Experimental.BuildCheck; using Microsoft.Build.Experimental.BuildCheck.Infrastructure; using Microsoft.Build.Framework; using Microsoft.Build.Shared; using InternalLoggerException = Microsoft.Build.Exceptions.InternalLoggerException; using LoggerDescription = Microsoft.Build.Logging.LoggerDescription; -using Microsoft.Build.Experimental.BuildCheck; #nullable disable @@ -1389,7 +1389,6 @@ private void StartLoggingEventProcessing() _emptyQueueEvent = new ManualResetEvent(false); _enqueueEvent = new AutoResetEvent(false); _loggingEventProcessingCancellation = new CancellationTokenSource(); - _loggingEventProcessingThread = new Thread(LoggingEventProc); _loggingEventProcessingThread.Name = $"MSBuild LoggingService events queue pump: {this.GetHashCode()}"; _loggingEventProcessingThread.IsBackground = true; @@ -1405,27 +1404,36 @@ void LoggingEventProc() if (_eventQueue.TryDequeue(out object ev)) { LoggingEventProcessor(ev); - _dequeueEvent.Set(); + _dequeueEvent?.Set(); } else { - _emptyQueueEvent.Set(); + _emptyQueueEvent?.Set(); - // Wait for next event, or finish. if (!completeAdding.IsCancellationRequested && _eventQueue.IsEmpty) { WaitHandle.WaitAny(waitHandlesForNextEvent); } - _emptyQueueEvent.Reset(); + lock (_lockObject) + { + try + { + _emptyQueueEvent?.Reset(); + } + catch (ObjectDisposedException) + { + // Might be thrown if the event was set as null in shutdown. + break; + } + } } } while (!_eventQueue.IsEmpty || !completeAdding.IsCancellationRequested); - _emptyQueueEvent.Set(); + _emptyQueueEvent?.Set(); } } - /// /// Clean resources used for logging event processing queue. ///