c# - .NET Core 中的短期运行后台任务

标签 c# asp.net-core .net-core

我刚刚发现了 IHostedService 和 .NET Core 2.1 BackgroundService 类。我认为这个想法很棒。 Documentation .

我找到的所有示例都用于长时间运行的任务(直到应用程序死掉)。 但我需要它的时间很短。哪种方法正确?

例如:
我想在应用程序启动后执行一些查询(它们将花费大约 10 秒)。并且仅当处于开发模式时。我不想延迟应用程序启动,所以 IHostedService 似乎是个好方法。我不能使用 Task.Factory.StartNew,因为我需要依赖注入(inject)。

目前我是这样做的:

public class UpdateTranslatesBackgroundService: BackgroundService
{
    private readonly MyService _service;

    public UpdateTranslatesBackgroundService(MyService service)
    {
        //MService injects DbContext, IConfiguration, IMemoryCache, ...
        this._service = service;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await ...
    }
}

启动:

public static IServiceProvider Build(IServiceCollection services, ...)
{
    //.....
    if (hostingEnvironment.IsDevelopment())
        services.AddSingleton<IHostedService, UpdateTranslatesBackgroundService>();
    //.....
}

但这似乎有些矫枉过正。是吗?注册单例(这意味着类在应用程序存在时存在)。我不需要这个。只需创建类、运行方法、处理类。全部在后台任务中。

最佳答案

无需施展任何魔法即可实现。

简单地:

  • ConfigureServices中注册你需要运行的服务
  • Configure中解析你需要的实例并运行。
  • 要避免阻塞,请使用 Task.Run

必须注册该实例,否则依赖注入(inject)将不起作用。这是不可避免的;如果您需要 DI,那么您就必须这样做。

除此之外,按照您的要求做是微不足道的,就像这样:

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
  }

  public IConfiguration Configuration { get; }

  // This method gets called by the runtime. Use this method to add services to the container.
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddTransient<MyTasks>(); // <--- This
  }

  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();

      // Blocking
      app.ApplicationServices.GetRequiredService<MyTasks>().Execute();

      // Non-blocking
      Task.Run(() => { app.ApplicationServices.GetRequiredService<MyTasks>().Execute(); });
    }
    else
    {
      app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseMvc();
  }
}

public class MyTasks
{
  private readonly ILogger _logger;

  public MyTasks(ILogger<MyTasks> logger)
  {
    _logger = logger;
  }

  public void Execute()
  {
    _logger.LogInformation("Hello World");
  }
}

BackgroundService 存在专门用于长时间运行的进程;如果是一次,请不要使用它。

关于c# - .NET Core 中的短期运行后台任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48321329/

相关文章:

c# - 我是否需要处理与应用程序本身具有相同生命周期的 IDisposable?

Javascript - 发送编码二进制 (zip) 文件数据并在 C# 中对其进行解码

c# - 在 TextBox 中使用 Bind 在 TextBox 控件外呈现绑定(bind)数据

Azure ServiceBus 单元测试

c# - 从 ASP.NET Core 3.1 端点流式传输数据而不消耗大量内存

c# - 无法使用 IOptionsMonitor 检测 ASP.NET Core 中的更改

.net-core - 如何配置 .net core 3.1 appsettings 以在 Github 操作上运行测试

c# - 错误 : The EntityFramework package is not installed on project

c# - C#/WPF 中的 NEON /发光效果

c# - Rabbitmq,在发布者之前重启消费者