A component that registers "fire and forget" tasks with the ASP.NET runtime.
C#
Latest commit 9318691 Jun 7, 2014 @StephenCleary Update README.md
Modified initial warning.
Permalink
Failed to load latest commit information.
src Added unit tests. Apr 4, 2014
.gitignore Added unit tests. Apr 4, 2014
LICENSE Initial commit Mar 3, 2014
README.md Update README.md Jun 7, 2014
icon.png Add icon. Apr 4, 2014

README.md

logo

Important Note

The .NET framework 4.5.2 introduced HostingEnvironment.QueueBackgroundWorkItem, which is very similar to this library. Consider upgrading to 4.5.2 and using HostingEnvironment.QueueBackgroundWorkItem instead of the BackgroundTaskManager.Run provided by this library.

Fire and Forget

This is one solution for a "fire and forget" scenario on ASP.NET: when you have enough data to send the response, but you still have additional work to do.

You want to return the response right away, but you also need to start the additional work in the background.

Important: "fire and forget" on ASP.NET is dangerous! Please read the discussion below to understand why!

How to Use

Download and install the Nito.AspNetBackgroundTasks NuGet package.

You can start background work by calling BackgroundTaskManager.Run:

BackgroundTaskManager.Run(() =>
{
  MyWork();
});

Run also understands asynchronous methods:

BackgroundTaskManager.Run(async () =>
{
  await MyWorkAsync();
});

If your background work is long-running or asynchronous, then use the BackgroundTaskManager.Shutdown cancellation token. This token is set when the ASP.NET runtime asks to shut down the application.

BackgroundTaskManager.Run(async () =>
{
  await MyWorkAsync(BackgroundTaskManager.Shutdown);
});

Finally, note that all exceptions are ignored. If you want to log exceptions, you'll have to do it yourself:

BackgroundTaskManager.Run(() =>
{
  try
  {
    MyWork();
  }
  catch (Exception ex)
  {
    Log(ex);
  }
});

The Problem with Fire and Forget

ASP.NET lives around a request lifecycle. If there are no active requests, ASP.NET may decide to unload your application. This is perfectly normal; by default ASP.NET will recycle your application every so often just to keep things clean.

This causes a problem for "fire and forget": ASP.NET isn't even aware that the background work is running. BackgroundTaskManager will register the background work with the ASP.NET runtime so it is aware of it. However, it's still not a perfectly reliable solution.

The Reliable Solution

The reliable way to handle this is complicated:

  • Add the background work to a reliable queue, such as an Azure queue or MSMQ.
  • Have an independent worker process that executes the work in the queue, such as an Azure WebJob, an Azure Worker Role, or a Win32 Service.
  • Determine some means to notify the end-user that the background processing has completed, such as email or SignalR.

One good, reliable solution is HangFire.

The Unreliable Solution

This solution is simpler, but dangerous: push the background work off to another thread within the ASP.NET process.

This solution is dangerous because it is not reliable; there is no guarantee that the background work will ever be done.

If your system needs the background work to be done, then you must use the proper, reliable solution above. There is no other way.

However, if you are perfectly OK with occasionally losing background work without a trace, then you can use the dangerous solution. For example, you have an on-disk cache that you want to update, but you don't want to slow down the requests. You want to send the response immediately and then update the on-disk cache in the background.

To reiterate: "fire and forget" on ASP.NET actually means "I don't care whether this work actually gets done or not".

Minimizing Unreliability

Just because the solution is unreliable, doesn't mean it must be totally unreliable.

AspNetBackgroundTasks is a NuGet package that allows you to register "fire and forget" work with the ASP.NET runtime. The unreliability is minimized; the danger is mitigated. It is still unreliable and dangerous, however.

Futher Reading

Phil Haack: "The Dangers of Implementing Recurring Background Tasks in ASP.NET"

Stephen Cleary: "Returning Early from ASP.NET Requests"