We have a Blazor Server application in .NET 7 running on IIS 10. This application contains a scoped service that is set to run everyday sometime between midnight and 1 a.m. The service compiles and emails an activity report for the just-concluded day to specific stakeholders.
However, for reasons unknown, the code does not appear to run on early Monday mornings (?!), so we never get a report for Sunday activity. It runs every other day, but skips Mondays. To troubleshoot, I added a line of code to email me everyday saying what day of the week yesterday was, and that specific email never arrives on early Monday mornings. It arrives every other day.
My understanding of services in Blazor is that if they encounter an uncaught exception they will terminate without taking any further action. We usually don't have activity on Saturdays or Sundays, but the Saturday-based report (sent very early on Sunday) executes without an issue and duly reports that there was no activity for Saturday.
Here is the relevant code:
public sealed class PhaseChangeReportService : IScopedProcessingService{ private readonly ILogger<PhaseChangeReportService> _logger; public PhaseChangeReportService(ILogger<PhaseChangeReportService> logger) { _logger = logger; } /// <summary> /// Runs continously (unless stopped), and sends the phase change report at scheduled times. Implementation is required by the IScopedProcessingService. /// </summary> /// <param name="stoppingToken">CancellationToken</param> /// <returns>a Task used by async methods</returns> public async Task DoWorkAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // If we are between midnight and 1 a.m., run the PhaseChange report. if (DateTime.Now > new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 00, 0)&& DateTime.Now <= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 1, 00, 0)) { SendPhaseChangeReport(); } // Wait one hour. await Task.Delay(1000 * 60 * 60, stoppingToken); } } /// <summary> /// Generates and sends a Phase Change Report email. /// </summary> private void SendPhaseChangeReport() { DateTime today = DateTime.Today; DateTime yesterday = DateTime.Today.AddDays(-1); // Get the PhaseChangeDtos. var allPhaseChangeDtos = GetPhaseChangeDtosByDate(yesterday, today); // Put them in order desired for the report. List<PhaseChangeDto> allPhaseChangeDtosSorted = allPhaseChangeDtos .ToList() .OrderBy(phaseChangeDto => phaseChangeDto.Project.Priority.PriorityOrder) .ThenBy(phaseChangeDto => phaseChangeDto.Project.FullName()) .ThenBy(phaseChangeDto => phaseChangeDto.Deliverable.BookNumber.CompactProjectTableGroupingName()) .ThenBy(phaseChangeDto => phaseChangeDto.Deliverable.DeliverableType.DeliverablesByUserOrder) .ThenBy(phaseChangeDto => phaseChangeDto.Deliverable.Enumeration) .ToList(); string body = FormatEmailBody(allPhaseChangeDtosSorted); MailFunctions.SendEmail("Neil Wehneman", [EMAIL], "Day of Week for " + yesterday.ToShortDateString(), "Yesterday was a " + yesterday.DayOfWeek +".", false); // If yesterday was a non-working day, only email the report to Neil. if (yesterday.DayOfWeek == System.DayOfWeek.Saturday || yesterday.DayOfWeek == System.DayOfWeek.Sunday || TextFunctions.Holidays.Contains(yesterday)) { MailFunctions.SendEmail("Neil Wehneman", [EMAIL], "Non-Working Day miniDARTS Phase Changes - " + yesterday.ToShortDateString(), body, true); } else { [EMAIL OTHER STAKEHOLDERS] } } [OTHER CLASS METHODS OMITTED FOR BREVITY]}