使用后台任务通过Web API发送计划的电子邮件

时间:2018-11-10 11:59:36

标签: asp.net-web-api backgroundworker

我对使用后台任务通过.NET核心Web API发送计划的电子邮件的方式进行了过多的研究。我知道最好在与应用程序域单独运行的Windows服务中实施后台任务。

但是我的要求是从Web客户端获取的,每行都有一个表,这是针对客户的促销活动,我可以选择激活,暂停,停止每个客户,然后从这里调用API。

我必须为每个可以同步运行的后台任务实现每个后台任务。我必须通过Web API来执行此操作,因为最终用户没有托管服务的地方。

实际解决方案

一天后,我想出了一种解决方案,该解决方案使用IHostedServiceBlockingCollection来控制运行时的后台任务,如下所示:

  

使用IHostedService进行后台任务的代码:

namespace SimCard.API.Worker
{
    internal class TimedHostedService : IHostedService, IDisposable
    {
        private CancellationTokenSource _tokenSource;
        private readonly ILogger _logger;
        private Timer _timer;
        private readonly TasksToRun tasks;
        private readonly IEmailService emailService;

        public TimedHostedService(ILogger<TimedHostedService> logger, TasksToRun tasks, IEmailService emailService)
        {
        this.emailService = emailService;
        this.tasks = tasks;
        _logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
       {
        tasks.Dequeue();
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
       }

       private void DoWork(object state)
       {
        emailService.SendEmail("ptkhuong96@gmail.com", "Test", "OK, Done now");
        _logger.LogInformation("Mail sent!");
       }

        public Task StopAsync(CancellationToken cancellationToken)
        {
        _logger.LogInformation("Timed Background Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
        }

       public void Dispose()
       {
        _timer?.Dispose();
       }
   }

}

  

这是BlockingCollection的代码:

namespace SimCard.API.Worker
{
    public class TasksToRun : ITasksToRun
    {
       private readonly BlockingCollection<int> _tasks;

       public TasksToRun() => _tasks = new BlockingCollection<int>();

       public void Enqueue(int settings) => _tasks.Add(settings);

       public void Dequeue() => _tasks.Take();
   }
}
  

然后从Web客户端调用控制器中的代码:

    [HttpPost("/api/worker/start")]

    public IActionResult Run()
    {
        tasks.Enqueue(15);
        return Ok();
    }
  

Startup.cs的代码:

    services.AddHostedService<TimedHostedService>();
    services.AddSingleton<TasksToRun, TasksToRun>();

问题:

  1. 在单击第一个事件的活动按钮后,将调用>控制器,并且将运行此后台任务的一个实例。如何暂停该任务并继续执行?
  2. 如果解决了第一个问题,我如何为表中的每个事件创建每个后台任务,请考虑一下我将来可能会创建越来越多的事件,如何激活,停止,暂停和恢复一个事件不影响另一个人?

我真的满足于此要求,并且不知道如何进一步进行。如果您有其他方法可以适应我的情况,也可以推荐我。

非常感谢您的支持。

0 个答案:

没有答案