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?
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.
Currently I am doing like this:
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 ...
}
}
startup:
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.
Simply:
ConfigureServices
Configure
and run it.Task.Run
.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
exists specifically for long running processes; if it's a once of, don't use it.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments