作者:dcl9784752 | 来源:互联网 | 2022-12-09 20:11
我想在ASPNET Core中实现一个可以按需停止和启动的定期(定时)IHostedService实例.我的理解是IHostedService是由应用程序启动时的框架启动的.
但是,我希望能够"手动"启动/停止服务,也许可以通过UI使用开/关切换.理想情况下,"关闭"状态将处置当前正在运行的服务,然后"开启"状态将创建新实例.
我在这里阅读了MS文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services? view = aspnetcore- 2.1.
我最初的想法是获取正在运行的服务的实例,然后调用public StopAsync(CancellationToken token)
方法.然而,当涉及到我应该传递哪个令牌时,我有点卡住了,对于该StartAsync(CancellationToken cancellationToken)
方法也可以这样说.
关于如何做到这一点的任何想法,或者它是否可取?我的方法是否违反了ASPNET Core中托管服务的预期设计?
编辑7.27.2018
因此,经过一些研究(也就是实际阅读文档:D)后,托管服务StartAsync/StopAsync方法确实意味着与应用程序的生命周期一致.注册的IHostedServices似乎没有添加到DI容器中以注入其他类.
因此,我认为我最初的想法不会起作用.现在我用配置依赖项(IOptions
)注册了我的服务,可以在运行时更新.当托管服务正在处理时,它将检查配置是否应该继续,否则它将等待(而不是停止或处置托管服务).
我很快就会将此标记为我的答案,除非我听到其他一些想法.
1> Tao Zhou..:
因为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 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();
启动和停止服务
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();
} }
关于如何防止“自动启动”的任何想法?
当您有多个服务时,如何处理HomeController(IHostedService hostedService)那一部分?如何指定要使用哪个?