简体   繁体   English

如何手动重启 ASP.net 核心中的 BackgroundService

[英]How to restart manually a BackgroundService in ASP.net core

I create the BackgroundService:我创建了后台服务:

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

and I added to the project:我添加到项目中:

public class Startup
{
    //...

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<CustomService>();

        //...
    }

    //...
}

How can I find the CustomService from another class?如何从另一个 class 找到 CustomService?
How to start it again?如何重新开始?

When it comes to controller's action, using "await BackgroundService.StartAsync" is the wrong way for long-running tasks.当涉及到控制器的操作时,使用“await BackgroundService.StartAsync”对于长时间运行的任务来说是错误的方法。

For instance, the main ussue could be request's timeout depended on proxy settings.例如,主要的问题可能是请求的超时取决于代理设置。

Here is an example how to make your BackgroundService restartable.这是一个如何使您的 BackgroundService 可重启的示例。

BackgroundService implementation:后台服务实现:

public class MyBackgroundService: BackgroundService
{
  private volatile bool _isFinished = false;
  private SemaphoreSlim _semaphore = new SemaphoreSlim(0,1);

  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
    _isFinished = false;
     // DoSomeWork
    _isFinished = true;
    await WaitToRestartTask(stoppingToken);
  }

  private async Task WaitToRestartTask(CancellationToken stoppingToken)
  {
     // wait until _semaphore.Release()
     await _semaphore.WaitAsync(stoppingToken);
     // run again
     await base.StartAsync(stoppingToken);
  }

  public void RestartTask()
  {
     if (!_isFinished)
          throw new InvalidOperationException("Background service is still working");

     // enter from _semaphore.WaitAsync
     _semaphore.Release();
  }  
}

Controller's action (for instance):控制器的动作(例如):

public async Task<IActionResult> Restart()
{
    var myBackgroundService= _serviceProvider.GetServices<IHostedService>()
                .OfType<MyBackgroundService>()
                .First();

    try
    {
       myBackgroundService.RestartTask();
       return Ok($"MyBackgroundService was restarted");
    }
    catch (InvalidOperationException exception)
    {
       return BadRequest(exception.Message);
    }
}

Create an interface just for the call to StartAsync :为调用StartAsync创建一个接口:

public interface ICustomServiceStarter
{
    Task StartAsync(CancellationToken token = default);
}

public class CustomService : BackgroundService, ICustomServiceStarter
{
    //...
    Task ICustomServiceStarter.StartAsync(CancellationToken token = default) => base.StartAsync(token);
    //...
}

Register the interface as a singleton:将接口注册为单例:

public class Startup
{
    //...
    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddSingleton<ICustomServiceStarter, CustomService>();
    }
    //...
}

and inject ICustomServiceStarter when needed:并在需要时注入ICustomServiceStarter

public class MyServiceControllerr : Controller
{
    ICustomServiceStarter _starter;

    public MyServiceController(ICustomServiceStarter starter)
    {
        _starter = starter;
    }

    [HttpPost]
    public async Task<IActionResult> Start()
    {
        await _starter.StartAsync();

        return Ok();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 ASP.net 内核中手动取消 BackgroundService - How to cancel manually a BackgroundService in ASP.net core 有没有办法在 Asp.Net core 3.1 中手动启动 BackgroundService - Is there a way to manually start BackgroundService in Asp.Net core 3.1 如何在 ASP.NET Core 2.1 中的计时器上运行 BackgroundService - How to run BackgroundService on a timer in ASP.NET Core 2.1 从asp.net core 2.1中的控制器访问BackgroundService - access BackgroundService from controller in asp.net core 2.1 在ASP.NET Core中启动BackgroundService的正确方法 - Correct way to start a BackgroundService in ASP.NET Core 在 ASP.NET Core 中处理 BackgroundService 中的非托管回调 - Handle unmanaged callback in BackgroundService in ASP.NET Core ASP.Net Core BackgroundService被无故取消 - ASP.Net Core BackgroundService is cancelled without reason asp.NET Core timed BackgroundService 不能在 Controller 中使用 StopAsync() 停止 - asp.NET Core timed BackgroundService cannot be stopped in Controller with StopAsync() 如何在 ASP.NET 核心应用程序中使用 BackgroundService 每年执行一个方法? - How can I execute a method every year using BackgroundService in ASP.NET core Application? 如何在Asp.net Core中手动验证JWT签名 - How to verify JWT signature manually in Asp.net Core
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM