.NET Core 中的短运行后台任务 [英] Short running background task in .NET Core

查看:27
本文介绍了.NET Core 中的短运行后台任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现了 IHostedService 和 .NET Core 2.1 BackgroundService 类.我认为想法很棒.文档.

I just discovered IHostedService and .NET Core 2.1 BackgroundService class. I think idea is awesome. Documentation.

我发现的所有示例都用于长时间运行的任务(直到应用程序死亡).但我需要它的时间很短.正确的做法是什么?

All examples I found are used for long running tasks (until application die). But I need it for short time. Which is the correct way of doing it?

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

For example:
I want to execute a few queries (they will take approx. 10 seconds) after application starts. And only if in development mode. I do not want to delay application startup so IHostedService seems good approach. I can not use Task.Factory.StartNew, because I need dependency injection.

目前我是这样做的:

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>();
    //.....
}

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

But this seems overkill. Is it? Register singleton (that means class exists while application lives). I don't need this. Just create class, run method, dispose class. All in background task.

推荐答案

没有必要为此做任何魔法.

There's no need to do any magic for this to work.

简单地说:

  • ConfigureServices
  • 中注册你需要运行的服务
  • Configure中解析你需要的实例并运行它.
  • 为避免阻塞,请使用 Task.Run.
  • Register the service you need to run in ConfigureServices
  • Resolve the instance you need in Configure and run it.
  • To avoid blocking, use Task.Run.

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

You must register the instance, or dependency injection won't work. That's unavoidable; if you need DI, then you have to do it.

除此之外,按照您的要求做就很简单了,就像这样:

Beyond that, it's trivial to do what you ask, like this:

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专门存在于长时间运行的进程中;如果是一次,请不要使用它.

BackgroundService exists specifically for long running processes; if it's a once of, don't use it.

这篇关于.NET Core 中的短运行后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆