Skip to content

Instantly share code, notes, and snippets.

@mahizsas
Forked from benerdin/IISTaskManager.cs
Last active August 29, 2015 14:16
Show Gist options
  • Save mahizsas/ce1979ae73db8a3db28b to your computer and use it in GitHub Desktop.
Save mahizsas/ce1979ae73db8a3db28b to your computer and use it in GitHub Desktop.
using NLog;
using System;
using System.Threading.Tasks;
using System.Web.Hosting;
namespace Web.Models
{
/// <summary>
/// Static class for running background tasks in IIS.
/// Any spawned threads are registered properly with IIS
/// to ensure they finish execution.
/// </summary>
public static class IISTaskManager
{
/// <summary>
/// Runs a background task that is registered with the hosting environment
/// so it is guaranteed to finish executing.
/// </summary>
/// <param name="action">The lambda expression to invoke.</param>
public static void Run(Action action)
{
new IISBackgroundTask().DoWork(action);
}
/// <summary>
/// Generic object for completing tasks in a background thread
/// when the request doesn't need to wait for the results
/// in the response.
/// </summary>
class IISBackgroundTask : IRegisteredObject
{
/// <summary>
/// Constructs the object and registers itself with the hosting environment.
/// </summary>
public IISBackgroundTask()
{
HostingEnvironment.RegisterObject(this);
}
/// <summary>
/// Called by IIS, once with <paramref name="immediate"/> set to false
/// and then again with <paramref name="immediate"/> set to true.
/// </summary>
void IRegisteredObject.Stop(bool immediate)
{
if (_task.IsCompleted || _task.IsCanceled || _task.IsFaulted || immediate)
{
// Task has completed or was asked to stop immediately,
// so tell the hosting environment that all work is done.
HostingEnvironment.UnregisterObject(this);
}
}
/// <summary>
/// Invokes the <paramref name="action"/> as a Task.
/// Any exceptions are logged
/// </summary>
/// <param name="action">The lambda expression to invoke.</param>
public void DoWork(Action action)
{
try
{
_task = Task.Run(action);
}
catch (AggregateException ex)
{
// Log exceptions
foreach (var innerEx in ex.InnerExceptions)
{
_logger.ErrorException(innerEx.ToString(), innerEx);
}
}
catch (Exception ex)
{
_logger.ErrorException(ex.ToString(), ex);
}
}
private Task _task;
private static Logger _logger = LogManager.GetCurrentClassLogger();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment