gpt4 book ai didi

c# - 如何手动取消 ASP.net 核心中的 BackgroundService

转载 作者:行者123 更新时间:2023-12-04 12:29:19 31 4
gpt4 key购买 nike

我创建了一个像这样的 BackgroundService:

public class CustomService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
do
{
//...

await Task.Delay(60000, cancellationToken);
}
while (!cancellationToken.IsCancellationRequested);
}
}
如何手动取消?

最佳答案

目前还不清楚您是要取消所有服务,也许是应用程序本身(或至少是主机),或者只是一个服务。
停止应用
要取消应用程序,请注入(inject) IHostApplicationLifetime类中的接口(interface)将强制取消并调用 StopApplication需要的时候。如果您想从后台服务本身内部取消,也许是因为没有其他事情可做,那就是您需要注入(inject)的地方。StopApplication将告诉主机应用程序需要关闭。主办方会调用StopAsync在所有托管服务上。由于您使用 BackgroundService , the implementation将触发 cancellationToken传递给 ExecuteAsync :

    public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executeTask == null)
{
return;
}

try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executeTask, Task.Delay(Timeout.Infinite, cancellationToken)).ConfigureAwait(false);
}

}
您根本不必更改当前代码。唯一担心的是 await Task.Delay()泄漏计时器。最好使用 Timer明确地,并在触发取消时处理它。
例如,如果您想从 Controller 操作中关闭应用程序:
public class MyServiceControllerr:Controller
{
IHostApplicationLifetime _lifetime;
public MyServiceController(IHostApplicationLifetime lifeTime)
{
_lifeTime=lifeTime;
}

[HttpPost]
public IActionResult Stop()
{
_lifeTime.StopApplication();
return Ok();
}
}
停止服务
如果你只想停止这一项服务,你需要一种方法来调用它的 StopAsync来自其他代码的方法。有很多方法可以做到这一点。一种这样的方法是注入(inject) CustomService给来电者并拨打 StopAsync .不过,这不是一个好主意,因为它公开了服务并将 Controller /停止代码与服务耦合。测试这也不容易。
另一种可能性是为调用 StopAsync 创建一个接口(interface)。 ,例如:
public interface ICustomServiceStopper
{
Task StopAsync(CancellationToken token=default);
}

public class CustomService : BackgroundService,ICustomServiceStopper
{
...

Task ICustomServiceStopper.StopAsync(CancellationToken token=default)=>base.StopAsync(token);

}

将接口(interface)注册为单例:
services.AddSingleton<ICustomServiceStopper,CustomService>();
并注入(inject) ICustomServiceStopper需要的时候:
public class MyServiceControllerr:Controller
{
ICustomServiceStopper _stopper;
public MyServiceController(ICustomServiceStopper stopper)
{
_stopper=stopper;
}

[HttpPost]
public async Task<IActionResult> Stop()
{
await _stopper.StopAsync();
return Ok();
}
}

关于c# - 如何手动取消 ASP.net 核心中的 BackgroundService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67898449/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com