diff --git a/src/Umbraco.Core/Services/NotificationService.cs b/src/Umbraco.Core/Services/NotificationService.cs index 72d46b2fb6..4c0661594c 100644 --- a/src/Umbraco.Core/Services/NotificationService.cs +++ b/src/Umbraco.Core/Services/NotificationService.cs @@ -565,49 +565,58 @@ public class NotificationService : INotificationService } } - private void Process(BlockingCollection notificationRequests) => - ThreadPool.QueueUserWorkItem(state => + private void Process(BlockingCollection notificationRequests) + { + // We need to suppress the flow of the ExecutionContext when starting a new thread. + // Otherwise our scope stack will leak into the context of the new thread, leading to disposing race conditions. + using (ExecutionContext.SuppressFlow()) { - if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) + ThreadPool.QueueUserWorkItem(state => { - _logger.LogDebug("Begin processing notifications."); - } - while (true) - { - // stay on for 8s - while (notificationRequests.TryTake(out NotificationRequest? request, 8 * 1000)) + if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { - try + _logger.LogDebug("Begin processing notifications."); + } + + while (true) + { + // stay on for 8s + while (notificationRequests.TryTake(out NotificationRequest? request, 8 * 1000)) { - _emailSender.SendAsync(request.Mail, Constants.Web.EmailTypes.Notification).GetAwaiter() - .GetResult(); - if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) + try { - _logger.LogDebug("Notification '{Action}' sent to {Username} ({Email})", request.Action, request.UserName, request.Email); + _emailSender.SendAsync(request.Mail, Constants.Web.EmailTypes.Notification).GetAwaiter() + .GetResult(); + if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) + { + _logger.LogDebug("Notification '{Action}' sent to {Username} ({Email})", request.Action, request.UserName, request.Email); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "An error occurred sending notification"); } } - catch (Exception ex) + + lock (Locker) { - _logger.LogError(ex, "An error occurred sending notification"); + if (notificationRequests.Count > 0) + { + continue; // last chance + } + + _running = false; // going down + break; } } - lock (Locker) + if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { - if (notificationRequests.Count > 0) - { - continue; // last chance - } - - _running = false; // going down - break; + _logger.LogDebug("Done processing notifications."); } - } - if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) - { - _logger.LogDebug("Done processing notifications."); - } - }); + }); + } + } private class NotificationRequest {