在ASP.NET Core RC2应用程序中定期运行后台任务

问题描述 投票:8回答:6

我正在研究ASP.NET Core RC2应用程序。此应用程序需要定期调用某些任务,例如发送电子邮件或调用特定的业务逻辑。

我知道有一些第三方库,如Hangfire或Quartz.NET,可以提供开箱即用的调度功能。但是我不认为其中任何一个当前都支持ASP.NET Core RC2。是否有任何其他可用的选项与ASP.NET Core RC2兼容?

如果没有,我想一个可能的选择是在一个单独的Windows服务中使用这些第三方库之一,然后可以定位支持的.NET版本。然后,该服务可以通过其Web API定期向ASP.NET应用程序发出请求,以便调用任务。

但是我不希望有单独的服务,因为它增加了移动部件的数量并使我们的应用程序的部署变得复杂。

c# asp.net asp.net-core quartz.net hangfire
6个回答
9
投票

手动方法:

  • 创建一个包含长期运行代码的Service,最好是async
  • 使用暂停(也最好是while)为服务添加async循环
  • 使用Task.Run(() => ...或在线程池(或传统的Thread)中在新线程中调用服务类的长时间运行方法。
  • 在Startup.cs中创建该类的实例
  • 在Startup.cs中使用services.AddSingleton(MyServiceInstance);中的Configure(...

3
投票
  • 如果您的目标是完整的.NET CLR,那么以前工作的任何库都可以使用。在RC2中没有改变。 Azure WebJobs是另一种解决方案,除了你已经提到的那些。
  • 对于CoreCLR,我不知道任何已经兼容的框架。您可能必须提出自己的解决方案,或者通过在完整的.NET中使用所有计划的代码或者在完整的.NET中调用CoreCLR来创建一个小应用程序来分解您的应用程序。

1
投票

我们使用一个简单的“任务运行器”应用程序,它接受命令行参数来确定要调用的Web / Windows服务。然后使用Windows任务计划程序调用“任务运行程序”应用程序。因此,服务是什么或者写入的技术并不重要。


1
投票

你总是可以给Quartz v3构建一个go。它已经在CoreCLR上运行,测试几乎已经过去了。您需要使用Visual Studio自己构建源代码。 See the v3 branch

目前最大的警告是不兼容的序列化,因为v2只能将二进制序列化为数据库(作业数据映射等),而v3仅支持JSON作为序列化格式。这个故事可能会改变,因为他们计划将BinaryFormatter带回来。

所以我会说如果你很乐意使用RAMJobStore而没有数据库持久性,你应该是金色的。它可能比手工制作的解决方案更好。


0
投票

ASP.NET Core支持使用托管服务运行后台任务,请参阅此doc。它有一个名为IHostedService的接口,用于用户定义的托管服务。该接口为主机管理的对象定义了两种方法:

  • StartAsync(CancellationToken) - 在服务器启动并且触发IApplicationLifetime.ApplicationStarted后调用。
  • StopAsync(CancellationToken) - 在主机执行正常关闭时触发。

您还可以通过实现ExecuteAsync方法继承抽象类BackgroundService,如下所示:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    stoppingToken.Register(() =>
            _logger.LogDebug($"Background task is stopping."));

    while (!stoppingToken.IsCancellationRequested)
    {
        _logger.LogDebug($"Background task doing work.");

        DoTask();

        await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
    }

}

定义托管服务后,需要将它们作为单例添加到ServiceCollection。然后这些后台任务将在asp.net核心应用程序中运行。


0
投票

考虑使用https://github.com/fluentscheduler/FluentScheduler

工作的例子很简单

JobManager.AddJob(() => Console.WriteLine("My job!"),
                 (s) => s.ToRunEvery(5).Seconds());
© www.soinside.com 2019 - 2024. All rights reserved.