Supress execution context flow when queuing email task. (#14571)
This commit is contained in:
@@ -565,49 +565,58 @@ public class NotificationService : INotificationService
|
||||
}
|
||||
}
|
||||
|
||||
private void Process(BlockingCollection<NotificationRequest> notificationRequests) =>
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
private void Process(BlockingCollection<NotificationRequest> 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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user