Ok, so after 48 hours of experimenting here's what I found:
1. It's fine to run background threads in ASP.NET _MVC_
If you're on MVC - just start your threads as normal, they won't be aborted after the current request ends:
//MVC - works just fine
public ActionResult ThreadTest()
{
new Thread(delegate() {
try
{
System.Threading.Thread.Sleep(10000);
}
catch(Exception ex)
{
//no exception will be thrown
}
}).Start();
return Content("ok");
}
2. For Web-Forms - use BackgroundWorker in combination with "Async" page attribute
I learned that with webforms you can't use:
new Thread().Start(); //not working
ThreadPool.QueueUserWorkItem //not working
Action.BeginInvoke //not working
A bunch of other things - all not working
Here's what you need to do:
1) Mark your page as "async" in .aspx (this will tell ASP.NET to inherit the page from IAsyncHandler)
<%@ Page language="c#" Async="true" %>
2) Use BackgroundWorker in .aspx.cs
protected void button1_Click(object sender, EventArgs e)
{
var bg = new BackgroundWorker();
bg.DoWork += delegate
{
try
{
Thread.Sleep(10000); //do nothing for 10 seconds
}
catch (Exception ex)
{
//no excpeiton is thrown
}
};
bg.RunWorkerAsync();
}
3. If you're on .NET 4.5.2 or higher - simply use HostingEnvironment.QueueBackgroundWorkItem
"The HostingEnvironment.QueueBackgroundWorkItem method lets you
schedule small background work items. ASP.NET tracks these items and
prevents IIS from abruptly terminating the worker process until all
background work items have completed. This method can't be called
outside an ASP.NET managed app domain."
Kudos to @danny-tuppeny for this last one
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…