c# - .NET Core 后台任务的神秘行为

标签 c# .net-core backgroundworker

我的第一个问题是 Microsoft 的这篇文章是否适用于其他程序员: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,其中数据输入被插入到一个数据库中。如果数据库中有新数据,我的后台作业应该每分钟显示一次,并且应该处理对其他网络服务的一些请求。

我的问题是,有时它会触发两次或作业未运行。每次后台服务执行时间戳时,我都会打印到控制台。过了一会儿,再也没有打印出来了。

这是我的示例代码。我的代码或配置有问题吗?

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();
    }
}

最佳答案

我通过使用提供的无限循环解决方案解决了这个问题。从现在开始,没有关于超时和取消任务的神秘行为。

解决方案如下所示:

     /// <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");
        while(true){
            //Do the business logic
            //Wait the time you want
        }
        return Task.CompletedTask;
    }



    /// <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();
    }
}

希望对你也有帮助。

关于c# - .NET Core 后台任务的神秘行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52147006/

相关文章:

c# - 取消后台任务

c# - 取消backgroundworker操作

.net-core - 从 .NET Core 中的 C# 访问 `.csproj` 属性

c# - 如何配置自包含的单文件程序?

c# - 在部署后处理 nHibernate/Fluent nHibernate 中的模式更新

c# - 如何在 MVC 5 的数据库中创建新表?

c# - Windows 上的 .NET Core 应用程序是否也可以访问 system.web?

c# - 带进度条的文件复制

c# - 禁用 Visual Studio 中特定文件的警告

c# - using语句用法