We are working with .NET Core Web Api, and looking for a lightweight solution to log requests with variable intensity into database, but don't want client's to wait for the saving process.
Unfortunately there's no HostingEnvironment.QueueBackgroundWorkItem(..)
implemented in dnx
, and Task.Run(..)
is not safe.
Is there any elegant solution?
相关问题
- Dotnet Core API - Get the URL of a controller meth
- Why am I unable to run dotnet tool install --globa
- Can I use MvcJsonOptions configured during Startup
- Singleton with AsyncLocal vs Scope Service
- What would prevent code running in a Docker contai
相关文章
- DotNet Core console app: An assembly specified in
- EF Core 'another instance is already being tra
- Re-target .NET Core to net471, net 472
- How to replace Middleware in integration tests pro
- Why CsvHelper not reading from MemoryStream?
- How to define function that returns html in asp.ne
- Publishing a Self-contained Console app fails
- Calling a .Net Framework 4 (or Mono) assembly from
Here is a tweaked version of Axel's answer that lets you pass in delegates and does more aggressive cleanup of completed tasks.
The original
HostingEnvironment.QueueBackgroundWorkItem
was a one-liner and very convenient to use. The "new" way of doing this in ASP Core 2.x requires reading pages of cryptic documentation and writing considerable amount of code.To avoid this you can use the following alternative method
The static
ConcurrentBag<Boolean> bs
will hold a reference to the object, this will prevent garbage collector from collecting the task after the controller returns.As @axelheer mentioned IHostedService is the way to go in .NET Core 2.0 and above.
I needed a lightweight like for like ASP.NET Core replacement for HostingEnvironment.QueueBackgroundWorkItem, so I wrote DalSoft.Hosting.BackgroundQueue which uses.NET Core's 2.0 IHostedService.
PM> Install-Package DalSoft.Hosting.BackgroundQueue
In your ASP.NET Core Startup.cs:
To queue a background Task just add
BackgroundQueue
to your controller's constructor and callEnqueue
.QueueBackgroundWorkItem
is gone, but we've gotIApplicationLifetime
instead ofIRegisteredObject
, which is being used by the former one. And it looks quite promising for such scenarios, I think.The idea (and I'm still not quite sure, if it's a pretty bad one; thus, beware!) is to register a singleton, which spawns and observes new tasks. Within that singleton we can furthermore register a "stopped event" in order to proper await still running tasks.
This "concept" could be used for short running stuff like logging, mail sending, and the like. Things, that should not take much time, but would produce unnecessary delays for the current request.
Such a
BackgroundPool
should be registered as a singleton and can be used by any other component via DI. I'm currently using it for sending mails and it works fine (tested mail sending during app shutdown too).Note: accessing stuff like the current
HttpContext
within the background task should not work. The old solution usesUnsafeQueueUserWorkItem
to prohibit that anyway.What do you think?
Update:
With ASP.NET Core 2.0 there's new stuff for background tasks, which get's better with ASP.NET Core 2.1: Implementing background tasks in .NET Core 2.x webapps or microservices with IHostedService and the BackgroundService class
You can use Hangfire (http://hangfire.io/) for background jobs in .NET Core.
For example :