C# Asp.Net-使用IHostedService的计划任务

C# Asp.Net-使用IHostedService的计划任务,c#,asp.net,iis,scheduled-tasks,C#,Asp.net,Iis,Scheduled Tasks,我正在开发一个ASP.NET web应用程序,它是用C#编写的,托管在Azure虚拟机上,使用IIS 10作为web服务器。我必须安排一个后台任务每天运行一次。为此,我创建了以下DailyTask类: public class DailyTask : IHostedService { public Task StartAsync(CancellationToken cancellationToken) { Debug.WriteLine("start");

我正在开发一个ASP.NET web应用程序,它是用C#编写的,托管在Azure虚拟机上,使用IIS 10作为web服务器。我必须安排一个后台任务每天运行一次。为此,我创建了以下
DailyTask
类:

public class DailyTask : IHostedService {

    public Task StartAsync(CancellationToken cancellationToken) {
        Debug.WriteLine("start");
        Task.Run(TaskRoutine, cancellationToken);
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken) {
        Debug.WriteLine("stop");
        return null;
    }

    public Task TaskRoutine() {
        while (true) {
            try {
                /* ... */

                DateTime nextStop = DateTime.Now.AddDays(1);
                var timeToWait = nextStop - DateTime.Now;
                var millisToWait = timeToWait.TotalMilliseconds;
                Thread.Sleep((int)millisToWait);
            }

            catch (Exception e) {
                Debug.WriteLine(e);
            }
        }
    }
}
public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        /* ... */
        services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, HiddenUserCleaner>();
        /* ... */
    }
}
要启动此任务,我在我的
Startup
类中添加了以下语句:

public class DailyTask : IHostedService {

    public Task StartAsync(CancellationToken cancellationToken) {
        Debug.WriteLine("start");
        Task.Run(TaskRoutine, cancellationToken);
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken) {
        Debug.WriteLine("stop");
        return null;
    }

    public Task TaskRoutine() {
        while (true) {
            try {
                /* ... */

                DateTime nextStop = DateTime.Now.AddDays(1);
                var timeToWait = nextStop - DateTime.Now;
                var millisToWait = timeToWait.TotalMilliseconds;
                Thread.Sleep((int)millisToWait);
            }

            catch (Exception e) {
                Debug.WriteLine(e);
            }
        }
    }
}
public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        /* ... */
        services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, HiddenUserCleaner>();
        /* ... */
    }
}
公共类启动{
public void配置服务(IServiceCollection服务){
/* ... */
services.AddSingleton();
/* ... */
}
}

在测试服务器上部署之后,我发现这个解决方案运行良好。但它可靠吗?如果在生产中使用会有问题吗?

它不安全。请看以下指南:

如果应用程序意外关闭(例如,应用程序的进程失败),则可能不会调用StopAsync。因此,在StopAsync中调用的任何方法或执行的任何操作都可能不会发生

事实并非如此,但它假设应用程序可以重新启动。偶尔重新启动的应用程序池也是如此

总的来说,这并不能保证它每天都运行。如果应用程序因任何原因频繁重启,则可能是它从未运行过

像hangfire这样的库也是如此


其他解决方案可以是web作业,也可以通过使用某种持久性(如存储上次执行时间的数据库)来检查它今天是否已执行,
IHostingService
将在每次启动时检查它是否应执行后台作业并相应地采取行动

您试图做的事情与使用Hangfire之类的框架类似,因此它也会遇到同样的问题,您应该回去查看替代方案。我在网上分享了一些提示