【发布时间】:2019-01-24 15:53:09
【问题描述】:
我的第一个问题是微软的这篇文章是否适用于其他程序员:https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/
解释了如何使用后台服务。我有一个程序,它有一个 WEB API,数据输入被插入到数据库中。如果数据库中有新数据,我的后台作业应该每分钟显示一次,并且应该处理对其他 web 服务的一些请求。
我的问题是,有时它会触发两次或作业没有运行。每次后台服务执行时间戳时,我都会打印到控制台。过了一会儿,就再也没有打印出来了。
这是我的示例代码。我的代码或配置有问题吗?
First Code-Sample 是 ConfigureService 方法中 Startup-Class 的代码:
//Adding Background Task Class to Hosted Services in Startup-Class and Method ConfigureServices
services.AddHostedService<JsonDataCreator>();
这里是保存我的后台服务逻辑的类的实现:
/// <summary>
/// Background Service which creates the JSON Files for the machine
/// </summary>
public class JsonDataCreator : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;
/// <summary>
/// Constructor
/// </summary>
/// <param name="logger">Logger functionallity</param>
public JsonDataCreator(ILogger<JsonDataCreator> logger)
{
_logger = logger;
}
/// <summary>
/// Task which is executed Asynchronous
/// </summary>
/// <param name="cancellationToken">Cancellation token for stopping the Task</param>
/// <returns>Task Completed</returns>
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is starting");
Console.WriteLine("Timed Background Service is starting");
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
return Task.CompletedTask;
}
/// <summary>
/// Logical Request to Webservice + Database and creation of JSON Files
/// </summary>
/// <param name="state"></param>
private void DoWork(object state)
{
try
{
Console.WriteLine("Begin new Round of Background-Work" + DateTime.Now.ToShortTimeString());
//THERE IS SOME LOGIC INSIDE WHICH CALLS SOME WEBSERVICE
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// Stops the Task
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>Task Completed</returns>
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is stopping");
Console.WriteLine("Timed Background Service is stopping");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
/// <summary>
/// Disposes the Task
/// </summary>
public void Dispose()
{
_timer?.Dispose();
}
}
【问题讨论】:
-
这里没有任何内容表明该任务将运行两次。当它停止运行时,您是否在日志中看到调用
StopAsync的等效消息?另外,我会销毁StopAsync中的计时器,而不是更改时间间隔。 -
@DavidG 神秘的东西是,后台任务是确定的,不再执行,但 stopasync 也没有被触发。所以我不知道问题出在哪里。后台任务通常是为这样的解决方案设计的吗?
-
@stuartd 没错。 StopAsync 等方法由接口命名。目前我不需要任何异步功能
-
你为什么不使用一个无休止的时间并删除计时器?它工作得很好,并且避免了线程(定时器)和任务的混合。
-
@MarioVernari 我想在下一个执行周期开始前等待一分钟
标签: c# .net-core backgroundworker