[Dev Tip] How to run Background Tasks in ASP.NET

A few years back Phil Haack wrote a great article on the dangers of recurring background tasks in ASP.NET. In it he points out a few gotchas that are SO common when folks try to do work in the background. Read it, but here’s a summary from his post.

  • An unhandled exception in a thread not associated with a request will take down the process.
  • If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time.
  • The AppDomain your site runs in can go down for a number of reasons and take down your background task with it.

If you think you can just write a background task yourself, it’s likely you’ll get it wrong. I’m not impugning your skills, I’m just saying it’s subtle. Plus, why should you have to?

There’s LOT of great ways for you to do things in the background and a lot of libraries and choices available.

Some ASP.NET apps will be hosted in IIS in your data center and others will be hosted in the Azure cloud. The spectrum of usage is roughly this, in my opinion:

  • General: Hangfire (or similar similar open source libraries)
    • used for writing background tasks in your ASP.NET website
  • Cloud: Azure WebJobs 
    • A formal Azure feature used for offloading running of background tasks outside of your Website and scale the workload
  • Advanced: Azure Worker Role in a Cloud Service
    • scale the background processing workload independently of your Website and you need control over the machine

There’s lots of great articles and videos on how to use Azure WebJobs, and lots of documentation on how Worker Roles in scalable Azure Cloud Services work, but not a lot about how your hosted ASP.NET application and easily have a background service. Here’s a few.


As it says “WebBackgrounder is a proof-of-concept of a web-farm friendly background task manager meant to just work with a vanilla ASP.NET web application.” Its code hasn’t been touched in years, BUT theWebBackgrounder NuGet package has been downloaded almost a half-million times.

The goal of this project is to handle one task only, manage a recurring task on an interval in the background for a web app.

If your ASP.NET application just needs one background task to runs an a basic scheduled interval, than perhaps you just need the basics of WebBackgrounder.

using System;
using System.Threading;
using System.Threading.Tasks;
namespace WebBackgrounder.DemoWeb
    public class SampleJob : Job
        public SampleJob(TimeSpan interval, TimeSpan timeout)
            : base("Sample Job", interval, timeout)
        public override Task Execute()
            return new Task(() => Thread.Sleep(3000));


Somewhat in response to the need for WebBackgrounder, .NET 4.5.2 added QueueBackgroundWorkItem as a new API. It’s not just a “Task.Run,” it tries to be more:

QBWI schedules a task which can run in the background, independent of any request. This differs from a normal ThreadPool work item in that ASP.NET automatically keeps track of how many work items registered through this API are currently running, and the ASP.NET runtime will try to delay AppDomain shutdown until these work items have finished executing.

It can try to delay an AppDomain for as long as 90 seconds in order to allow your task to complete. If you can’t finish in 90 seconds, then you’ll need a different (and more robust, meaning, out of process) technique.

The API is pretty straightforward, taking  Func<CancellationToken, Task>. Here’s an example that kicks of a background work item from an MVC action:

public ActionResult SendEmail([Bind(Include = "Name,Email")] User user)
    if (ModelState.IsValid)
       HostingEnvironment.QueueBackgroundWorkItem(ct => SendMailAsync(user.Email));
       return RedirectToAction("Index", "Home");
    return View(user);


FluentScheduler is a more sophisticated and complex scheduler that features a (you guessed it) fluent interface. You have really explicit control over when your tasks run.

using FluentScheduler;
public class MyRegistry : Registry
    public MyRegistry()
        // Schedule an ITask to run at an interval
        // Schedule a simple task to run at a specific time
        Schedule(() => Console.WriteLine("Timed Task - Will run every day at 9:15pm: " + DateTime.Now)).ToRunEvery(1).Days().At(21, 15);
        // Schedule a more complex action to run immediately and on an monthly interval
        Schedule(() =>
            Console.WriteLine("Complex Action Task Starts: " + DateTime.Now);
            Console.WriteLine("Complex Action Task Ends: " + DateTime.Now);
        }).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);

FluentScheduler also embraces IoC and can easily plug into your favorite Dependency Injection tool of choice by just implementing their ITaskFactory interface.


Quartz.NET is a .NET port of the popular Java job scheduling framework of the (almost) same name. It’s very actively developed. Quartz has an IJob interface with just one method, Execute, to implement.

using Quartz;
using Quartz.Impl;
using System;
namespace ScheduledTaskExample.ScheduledTasks
    public class JobScheduler
        public static void Start()
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            IJobDetail job = JobBuilder.Create<MyJob>().Build();
            ITrigger trigger = TriggerBuilder.Create()
                  (s =>
                    .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
            scheduler.ScheduleJob(job, trigger);

Then, inside your Application_Start, you call JobScheduler.Start(). There’s a great getting started article on Quartz at Mikesdotnetting you should check out.


And last but definitely not least, the most polished (IMHO) of the group, Hangfire by @odinserj. It’s afantastic framework for background jobs in ASP.NET. It’s even optionally backed by Redis, SQL Server, SQL Azure, MSMQ, or RabbitMQ for reliability.

The Hangfire documentation is amazing, really. Every open source project’s document should be this polished. Heck, ASP.NET’s documentation should be this good.

The best feature from Hangfire is its built in /hangfire dashboard that shows you all your scheduled, processing, succeeded and failed jobs. It’s really a nice polished addition.


You can enqueue “fire and forget” jobs easily and they are backed by persistent queues:

BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));

You can delay them…

BackgroundJob.Schedule(() => Console.WriteLine("Delayed"), TimeSpan.FromDays(1));

Or great very sophisticated CRON style recurrent tasks:

RecurringJob.AddOrUpdate(() => Console.Write("Recurring"), Cron.Daily);

Hangfire is just a joy.

Check out the Hangfire Highlighter Tutorial for a sophisticated but easy to follow real-world example.

There’s a rich ecosystem out there ready to help you with your background tasks. All these libraries are excellent, are open source, and are available as NuGet Packages.

Did I miss your favorite? Sound off in the comments!

Ref: http://www.hanselman.com/blog/CategoryView.aspx?category=NuGetPOW

[Discovery] Các nhà nghiên cứu đã khám phá ra loại protein có thể ngăn chặn sự phát tác của virus HIV và Ebola

virus_3d. ​Mới đây, các nhà khoa học đã bất ngờ tìm thấy một nhóm protein có khả năng ngăn chặn quá trình xâm nhập của HIV type 1 (HIV-1) vào những tế bào mới. Một điều thú vị khác là loại protein này còn có thể ức chế sự phát tán của những chủng virus khác bao gồm cả virus Ebola. Trước tình hình Ebola có thể lây lan thành một đại dịch trên toàn cầu, phát hiện trên không chỉ giúp các nhà khoa học có thêm hiểu biết về sự tương tác giữa virus và protein trong cơ thể người mà còn góp phần mở đường sứ mạng tìm kiếm phương pháp ngăn chặn sự lây lan của các đại dịch nguy hiểm trong tương lai không xa.

Về cơ bản, virus không có khả năng tự tái tạo nên chúng phải đi chiếm một tế bào chủ khác để duy trì sự sống. Để xâm nhập vào bên trong tế bào chủ, HIV hoặc các chủng virus suy giảm miễn dịch khác cần phải liên kết với các thụ thể tồn tại bên trong tế bào mục tiêu. Tiếp theo đó là nhiều sự kiện diễn ra nhằm phục vụ quá trình xâm nhập của HIV. Sau khi đã xâm nhập thành công virus sẽ chuyển đổi tế bào thành một nhà máy có nhiệm vụ tiếp tục sản sinh thêm virus.

Các nghiên cứu gần đây đã phát hiện ra một nhóm protein mang tên TIM protein. Đây là loại protein có vai trò quan trọng để tạo điều kiện cho sự xâm nhập của nhiều loại virus như Ebola, siêu vi Tây sông Nile (West Nile) và cả virus gây bệnh sốt xuất huyết. Một cách hết sức bất ngờ, nhóm các nhà nghiên cứu tại Đại học Missouri đã phát hiện thêm rằng các protein trên không chỉ có khả năng ngăn chặn quá trình xâm nhập của HIV-1 vào tế bào chủ mà còn ngăn chặn sự phát tán của virus.

Trong nhiều thí nghiệm, các nhà khoa học đã nghiên cứu sự tương tác giữa HIV-1 và protein TIMbằng các biện pháp phân tử, hóa sinh và các kỹ thuật quan sát dưới kính hiển vi. Cuối cùng, các nhà nghiên cứu đã phát hiện rằng khi HIV-1 bắt đầu tạo mầm mống hoặc chuẩn bị phát tán ra khỏi tế bào chủ, protein TIM sẽ gắn kết vào cấu trúc của virus và trói buộc nó vào màn tế bào. Đây là cấu trúc trung gian được hình thành nhờ vào sự tương tác với một loại chất béo mang tên phosphatidylserine (PS) được tìm thấy trong màng tế bào và nên ngoài bề mặt virus.

Thông thường, PS sẽ được vận chuyển vào bên trong tế bào, nhưng sự lây nhiễm virus làm nó bị loại trở lại bên ngoài. Điều này có nghĩa là cả PS và TIM đều tồn tại ở cả tế bào lẫn trên bề mặt virus. Nói một cách nôm na, PS và TIM đã cùng nhau giúp buộc chặt virus ở bên ngoài màng tế bào khiến nó không thể nào xâm nhập và tiếp tục lây lan được nữa.

Mặt khác, điều thú vị ở đây là nhóm đã khám phá rằng protein TIM cũng có khả năng ức chế sự lây nhiễm của những chủng virus khác, bao gồm cả những loại virus cơ hội như HIV và Ebola. Tuy nhiên, cho tới hiện tại, các nhà nghiên cứu vẫn chưa xác định được tương tác giữa protein TIM và virus là nhân tố tích cực hay tiêu cực. Tuy nhiên, người dẫn đầu nhóm nghiên cứu cho rằng phát hiện này đã gia tăng sự hiểu biết của các nhà khoa học về sự tương tác giữa virus với cơ thể người, qua đó mở đường cho quá trình đề xuất liệu pháp chống virus trong tương lai.

Tham khảo: Đại học Missouri, PNAS, SD, IFS