【问题标题】:How to run a service on startup like controller?如何在启动时像控制器一样运行服务?
【发布时间】:2021-05-25 04:01:56
【问题描述】:

我需要在应用程序开始运行后立即运行 MyService。我希望像在控制器中那样自动解析 DI,这样我就不必像现在在 Program.cs 中那样获得服务:var someDependency = services.GetRequiredService<ISomeDependency>

private readonly ISomeDependency some;
public void Here()
{
    MyService(some);
}

【问题讨论】:

  • 在启动Configure方法中最后声明
  • 它不起作用,因为 Startup 的构造函数不了解依赖项是什么。
  • 使用 dotnet core 2.1 及更高版本,您可以使用 Microsoft 提供的 Microsoft.Extensions.Hosting 包添加对非 Web 托管后台服务和依赖注入配置的支持

标签: .net-core


【解决方案1】:

试试 IHostedService - https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/ 它适用于我们所有的自托管网站。

    internal abstract class HostedService : IHostedService
{
    private CancellationTokenSource _cts;
    private Task _executingTask;

    protected ILogger Logger { get; }

    protected HostedService(ILoggerFactory loggerFactory)
    {
        Logger = loggerFactory.CreateLogger(GetType());
    }

    public virtual Task StartAsync(CancellationToken cancellationToken)
    {
        // Create a linked token so we can trigger cancellation outside of this token's cancellation
        _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

        // Store the task we're executing
        _executingTask = ExecuteAsync(_cts.Token);

        Logger.LogInformation($"{GetType().Name} started");

        // If the task is completed then return it, otherwise it's running
        return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
    }

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

        // Signal cancellation to the executing method
        _cts.Cancel();

        // Wait until the task completes or the stop token triggers
        await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));

        Logger.LogInformation($"{GetType().Name} stopped");

        // Throw if cancellation triggered
        cancellationToken.ThrowIfCancellationRequested();
    }

    // Derived classes should override this and execute a long running method until 
    // cancellation is requested
    protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
}

internal class MyService : HostedService
{
    private readonly ISomeDependency _someDependency;

    public MyService(ISomeDependency someDependency)
    {
        _someDependency = someDependency;
    }

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            _someDependency.DoSmths();
        }
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHostedService, MyService>();
    }
}

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-06
  • 2021-01-22
  • 1970-01-01
  • 2014-09-27
  • 1970-01-01
相关资源
最近更新 更多