What's the Current and Recommended Way to Fire Off an Asynchronous Thread?
I have an ASP.NET MVC 3 (.NET 4) web application.
I have a [HttpPost]
action method which submit's some data to the database.
Now, after this method is finishing persisting to the repository, i wish to execute a "background" task (think auditing, or sending an email, etc), where i don't care about the result (unless an error occurs, in which case i'll perform logging).
How can/should i fire off this task from my action method?
[HttpPost]
[Authorize]
public ActionResult Create(MyViewModel model)
{
if (ModelState.IsValid)
{
_repo.Save(model);
// TODO: Fire off thread
return RedirectToRoute("Somepage", new { id = model.id }开发者_Go百科);
}
return View(model);
}
The new .NET 4 way to do this is with a Task
.
http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx
Task.Factory.StartNew(MyBackgroundAction);
But for this simple operation where you just want to run it and don't care about coordinating tasks, it's just as easy to use the ThreadPool.
ThreadPool.QueueUserWorkItem(MyBackgroundAction)
You want to avoid creating a new Thread yourself for every action--it'll take up more resources and is unnecessarily wasteful.
If you're background tasks are longer running you might want to setup a producer/consumer queue and have a single or set number of constantly running background threads to run the tasks.
It is in general ill-advised to use the Thread Pool in ASP.Net for asynchronous tasks.
Note that this question is touched on here, although I do not agree with the answer. The accepted answer assumes that you need the work done now, when for an asynchronous task as described by this question can easily be done later. This allows processing to be spread over a longer period of time, useful when load is not uniform (like most web pages).
Spawning threads for every request is also suboptimal, since there is no easy way to bound the number of threads created. 100 spawned tasks will compete with your web application trying to do "real time" work.
Use a messaging system to manage asynchronous tasks that do not need to be immediately run. Each request to process gets sent as a message which is queued up to be processed later. You can then have a separate application on either the local system, or if these tasks take considerable processing on other machines. You can easily spread the load of these tasks too, by running the processor on multiple machines that all pull from the same queue.
In the past I have used MSMQ to good effect.
// Fire off thread
var t = new System.Threading.Thread(() =>
{
// do whatever
});
t.Start();
In the "do whatever" you should have try/catch that logs any exceptions.
精彩评论