ASP.NET Core IHostedService 手动启动/停止/暂停(?) [英] ASP.NET Core IHostedService manual start/stop/pause(?)

查看:124
本文介绍了ASP.NET Core IHostedService 手动启动/停止/暂停(?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 ASPNET Core 中实现一个可以按需停止和启动的循环(定时)IHostedService 实例.我的理解是 IHostedService(s) 在应用程序启动时由框架启动.

I would like to implement a recurring (timed) IHostedService instance in ASPNET Core that can be stopped and started on demand. My understanding is that IHostedService(s) are started by the framework on application startup.

但是,我希望能够手动"启动/停止服务,也许可以通过 UI 使用开/关切换.理想情况下,关闭"状态将处理当前正在运行的服务,然后开启"状态将创建一个新实例.

However, I would like to be able to start/stop the service 'manually', perhaps using an on/off toggle via a UI. Ideally the "off" state would dispose of currently running service, and the "on" state would then create a new instance.

我在这里阅读了 MS 文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1.

I've read the MS docs here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1.

我最初的想法是获取正在运行的服务的实例,然后调用公共 StopAsync(CancellationToken token) 方法.然而,当涉及到我应该传入哪个令牌时,我有点困惑,对于 StartAsync(CancellationToken cancellingToken) 方法也是如此.

My initial thought was to get an instance of the running service and then call the public StopAsync(CancellationToken token) method. However I'm a little stuck when it comes to which token I should pass in, and the same could be said for the StartAsync(CancellationToken cancellationToken) method.

关于如何做到这一点的任何想法,或者甚至是可取的?我的方法是否与 ASPNET Core 中托管服务的预期设计背道而驰?

Any ideas on how this should be done, or if it's even advisable? Is my approach somehow going against the intended design of hosted services in ASPNET Core?

编辑 7.27.2018

因此,经过更多研究(也就是实际上阅读文档:D),托管服务的 StartAsync/StopAsync 方法确实意味着与应用程序的生命周期一致.注册的 IHostedServices 似乎没有添加到 DI 容器中以注入其他类.

So it appears after some more research (aka actually reading the documentation :D) that hosted services StartAsync/StopAsync methods are indeed meant to coincide with the lifetime of the application. Registered IHostedServices seem to not be added to the DI container for injection into other classes.

因此,我认为我最初的想法行不通.现在,我使用可以在运行时更新的配置依赖项 (IOptions) 注册了我的服务.当托管服务正在处理时,它会检查配置以查看它是否应该继续,否则它只会等待(而不是停止或处置托管服务).

Therefore I do not think my initial idea will work. For now I registered my services with configuration dependencies (IOptions<T>) that can be updated at runtime. As the hosted services is processing, it will check the configuration to see if it should continue, otherwise it will just wait (instead of stopping or disposing of the hosted service).

我可能很快会将此标记为我的答案,除非我听到其他一些想法.

I'll probably mark this as my answer soon, unless I hear of some other ideas.

推荐答案

对于StopAsync(CancellationToken token),你可以通过new System.Threading.CancellationToken().在public CancellationToken(bool cancelled)的定义中,canceled表示token的状态.对于您的场景,由于您要停止服务,因此无需指定 canceled.

For StopAsync(CancellationToken token), you could pass new System.Threading.CancellationToken(). In the defination of public CancellationToken(bool canceled), canceled indicates state for the token. For your scenario, there is no need to specify the canceled since you want to Stop the service.

您可以按照以下步骤进行操作:

You could follow below step by step:

  1. 创建IHostedService

   public class RecureHostedService : IHostedService, IDisposable
 {
private readonly ILogger _log;
private Timer _timer;
public RecureHostedService(ILogger<RecureHostedService> log)
{
    _log = log;
}

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

public Task StartAsync(CancellationToken cancellationToken)
{
    _log.LogInformation("RecureHostedService is Starting");
    _timer = new Timer(DoWork,null,TimeSpan.Zero, TimeSpan.FromSeconds(5));
    return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
    _log.LogInformation("RecureHostedService is Stopping");
    _timer?.Change(Timeout.Infinite, 0);
    return Task.CompletedTask;
}
private void DoWork(object state)
{
    _log.LogInformation("Timed Background Service is working.");
}
}

  • 注册IHostedService

        services.AddSingleton<IHostedService, RecureHostedService>();
    

  • 启动和停止服务

  • Start and Stop Service

     public class HomeController : Controller {
     private readonly RecureHostedService _recureHostedService;
     public HomeController(IHostedService hostedService)
     {
         _recureHostedService = hostedService as RecureHostedService;
     }
     public IActionResult About()
     {
         ViewData["Message"] = "Your application description page.";
         _recureHostedService.StopAsync(new System.Threading.CancellationToken());
         return View();
     }
    
     public IActionResult Contact()
     {
         ViewData["Message"] = "Your contact page.";
         _recureHostedService.StartAsync(new System.Threading.CancellationToken());
         return View();
     } }
    

  • 这篇关于ASP.NET Core IHostedService 手动启动/停止/暂停(?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆