使用HostedService进行后台任务管理

时间:2019-03-26 09:06:17

标签: c# .net-core scheduled-tasks

我正在构建一个dotnet核心GenericHost应用程序,该应用程序启动动态数量的计划任务,该任务需要能够在数据库中更新每个任务时有选择地取消它们,但是我不确定采用哪种最佳方法

我已经建立了应用程序的基本框架,在进行了一些研究之后,我遇到了以下两种方法,我不确定哪种方法更有效/更能证明未来,并且我不确定确保遵循什么设计模式来跟踪预定任务及其相关的CancellationToken:

  1. Queued Background tasks

  2. Building a scheduled task ASP.NET Core/Standard 2.0

关于监视运行时间表及其相关的CancellationToken,我目前的想法是,我将这些信息存储在Dictionary中,其中时间表数据库ID为键,而CancellationToken为值。

方法1产生以下代码来排队新的后台工作项,并且似乎每个任务共享由QueuedHostedService设置的相同CancellationToken:

foreach (var schedule in schedules) {
   // Enqueue a background work item
   _taskQueue.QueueBackgroundWorkItem(async token => {
      dict.Add(schedule.Id, token);

      var guid = Guid.NewGuid().ToString();

      for (var delayLoop = 0; delayLoop < 3; delayLoop++) {
         _logger.LogInformation($"Queued Background Task {guid} is running. {delayLoop}/3");

         await Task.Delay(TimeSpan.FromSeconds(5), token);
      }

      _logger.LogInformation($"Queued Background Task {guid} is complete. 3/3");
   });
}

方法2产生以下代码,我强制每个启动的任务使用新的CancellationTokenSource:

foreach (var schedule in schedules) {
   schedule.Increment();

   var tokenSource = new CancellationTokenSource();

   await taskFactory.StartNew(async () => {
      try {
        await schedule.Task.ExecuteAsync(tokenSource);
      } catch (Exception ex) {
         var args = new UnobservedTaskExceptionEventArgs(ex as AggregateException ?? new AggregateException(ex));

         UnobservedTaskException?.Invoke(this, args);

         if (!args.Observed) {
            throw;
         }
      }
   }, cancellationToken);

   dict.Add(schedule.Id, tokenSource.Token);
}

0 个答案:

没有答案