c# - ASP.NET Core IHostedService 手动启动/停止/暂停(?)
问题描述
我想在 ASPNET Core 中实现一个循环(定时)IHostedService 实例,该实例可以按需停止和启动。我的理解是 IHostedService(s) 是由框架在应用程序启动时启动的。
但是,我希望能够“手动”启动/停止服务,也许可以通过 UI 使用开/关切换。理想情况下,“关闭”状态将处理当前正在运行的服务,而“开启”状态将创建一个新实例。
我在这里阅读了 MS 文档:https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1 。
我最初的想法是获取正在运行的服务的实例,然后调用公共StopAsync(CancellationToken token)
方法。但是,当涉及到我应该传递哪个令牌时,我有点卡住了,StartAsync(CancellationToken cancellationToken)
方法也是如此。
关于如何做到这一点的任何想法,或者甚至是可取的?我的方法是否在某种程度上违背了 ASPNET Core 中托管服务的预期设计?
编辑 7.27.2018
因此,经过更多研究(也就是实际阅读文档:D)后,托管服务的 StartAsync/StopAsync 方法确实与应用程序的生命周期相吻合。注册的 IHostedServices 似乎没有添加到 DI 容器中以注入其他类。
因此,我认为我最初的想法不会奏效。IOptions<T>
现在,我使用可以在运行时更新的配置依赖项 () 注册了我的服务。当托管服务正在处理时,它将检查配置以查看它是否应该继续,否则它将只是等待(而不是停止或处置托管服务)。
除非我听到其他想法,否则我可能很快就会将此标记为我的答案。
解决方案
因为StopAsync(CancellationToken token)
,你可以通过new System.Threading.CancellationToken()
。在 的定义中public CancellationToken(bool canceled)
,canceled
表示令牌的状态。对于您的方案,无需指定 ,canceled
因为您要停止服务。
您可以按照以下步骤逐步操作:
创造
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>();
启动和停止服务
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(); } }
推荐阅读
- python - 查找出现在多列中的相同值
- c# - C#使用反射创建函数
- json - SwiftUI - 如何附加和显示嵌套的 JSON 数据
- c# - 在 C# 中使用 linq 查询将字符串从拳头名拆分为姓氏
- python - 在 Python 3 中使用正则表达式
- javascript - 自动将文本转换为行和列(Google 表格)
- android - Xamarin - 该项目缺少构建所需的 Android SDK
- angular - 如何在 Firebase onSnapshot 中使用 .catch
- python - 系统启动时执行 python 脚本
- vba - 在 MS-Word VBA 中使用 APPLICATION.QUIT 但应用程序立即重新打开