我有一个ASP.NET MVC 3(.NET 4)Web应用程序。
我有一个[HttpPost]
操作方法,可以将一些数据提交给数据库。
现在,在此方法完成持久存储到存储库后,我希望执行“后台”任务(想想审核,或发送电子邮件等),我不关心结果(除非发生错误) ,在这种情况下,我将执行记录)。
我怎么能/应该从我的行动方法中解雇这个任务?
[HttpPost]
[Authorize]
public ActionResult Create(MyViewModel model)
{
if (ModelState.IsValid)
{
_repo.Save(model);
// TODO: Fire off thread
return RedirectToRoute("Somepage", new { id = model.id });
}
return View(model);
}
答案 0 :(得分:4)
新的.NET 4方法是使用Task
。
http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx
Task.Factory.StartNew(MyBackgroundAction);
但是对于这个简单的操作,你只想运行它并且不关心协调任务,使用ThreadPool也同样容易。
ThreadPool.QueueUserWorkItem(MyBackgroundAction)
您希望避免为每个操作自己创建一个新线程 - 它会占用更多资源并且不必要地浪费。
如果您的后台任务运行时间较长,您可能需要设置生产者/消费者队列,并拥有一组或一定数量的持续运行的后台线程来运行任务。
答案 1 :(得分:2)
异步任务通常是ill-advised to use the Thread Pool in ASP.Net。
请注意here已触及此问题,但我不同意答案。接受的答案假定您需要完成现在的工作,而对于此问题所描述的异步任务可以在以后轻松完成。这允许处理分布更长的时间,当负载不均匀时很有用(像大多数网页一样)。
为每个请求生成线程也不是最理想的,因为没有简单的方法来限制创建的线程数。 100个衍生任务将与您的Web应用程序竞争,试图进行“实时”工作。
使用消息传递系统来管理不需要立即运行的异步任务。每个处理请求都作为一个消息发送,该消息排队等待稍后处理。然后,您可以在本地系统上拥有单独的应用程序,或者如果这些任务在其他计算机上进行大量处理。通过在同一队列中拉出的多台计算机上运行处理器,您也可以轻松地分散这些任务的负载。
过去我使用MSMQ效果很好。
答案 2 :(得分:0)
// Fire off thread
var t = new System.Threading.Thread(() =>
{
// do whatever
});
t.Start();
在“做任何事情”中你应该尝试/捕捉记录任何异常。