将方法抛出到Task中以避免阻塞asp.net线程

时间:2011-05-02 19:55:58

标签: c# asp.net task

我想知道以下代码是否有任何在网络服务器上运行时我不知道的问题。阅读优秀系列http://reedcopsey.com/series/parallelism-in-net4/我无法找到任何与我的问题有关的内容,与msdn一样,所以我想我会把它带到这里。

示例电话:

public ActionResult Index() {
    ViewBag.Message = "Welcome to ASP.NET MVC!";

    Task.Factory.StartNew(() => {
        //This is some long completing task that I don't care about
        //Say logging to the database or updating certain information
        System.Threading.Thread.Sleep(10000);
    });

    return View();
}

3 个答案:

答案 0 :(得分:5)

ASP.Net支持异步页面,请参阅Asynchronous Pages in ASP.NET,但它是一个复杂的编程模型,并且根本不与MVC绑定。话虽这么说,从同步请求处理程序启动异步任务可以解决问题:

  • 如果请求添加新任务的速率超过平均处理速率,您的进程最终将崩溃。任务占用了实时内存,最终它们将填满存储它们的内存队列,并且您将开始无法提交。
  • .Net Taks本身就不可靠,因为它们缺少持久存储,因此所有提交异步的任务必须作为'abandonware'进行线程化,即。如果它们永远不会完成,那么应用程序或提出请求的用户都不会有任何损失。如果任务很重要,则必须通过可靠的机制提交,以确保在出现故障时执行,如Asynchronous procedure execution中提供的那样。

答案 1 :(得分:4)

在这种情况下,一个重要的事情是确保任务中包含的代码包装在try / catch块中,或者在此线程中抛出的任何可能的异常都将传播。您还应该确保在这个长时间运行的任务中,您没有访问任何Http Context成员,例如Request,Response,Session ......,因为它们在您访问它们时可能不再可用。

答案 2 :(得分:0)

使用new Thread代替Task.Factory.StartNewTask.Factory.StartNew使用来自线程池的线程,如果你有许多后台任务,线程池将耗尽线程并降低你的web应用程序。请求将排队,您的网络应用程序最终将死亡:)

您可以使用Thread.CurrentThread.IsThreadPoolThread测试在线程池上执行的后台工作。如果你得到True,则使用线程池。