2011-05-02 48 views
11

我在想以下代码是否有任何我在Web服务器上运行时不知道的问题。阅读优秀系列http://reedcopsey.com/series/parallelism-in-net4/我无法找到任何与我的问题特别相关的内容,与msdn一样,所以我想我会把它带到这里。将方法引入任务以避免阻塞asp.net线程

调用示例:

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(); 
} 
+0

相关:http://stackoverflow.com/questions/3994085/are-there-any-non-obvious-dangers-in-using-threads-in-asp-net – 2011-05-02 20:16:37

+0

感谢您的链接乔恩。我没有考虑过的一条途径,但现在对我来说显而易见的是“由于AppPool被回收”,他们可能随时死亡。绝对是我必须考虑的事情。虽然我不认为这会影响那么多,因为我不关心他们* – Buildstarted 2011-05-02 20:26:16

回答

5

ASP.Net支持异步页,看到Asynchronous Pages in ASP.NET,但它是一个复杂的编程模型,并且不与MVC在所有绑定。话虽这么说,从同步请求处理工作在一定程度上启动异步任务:

  • 如果在该请求添加新任务的速度超过处理您的过程最终会崩溃的平均速率。任务会占用实时内存,最终他们将填满内存中的内存队列,并且您的注册表将开始无法提交。
  • 。由于它们缺乏持久性存储,所以网络固有地不可靠,因此所有提交异步的任务都必须作为“放弃软件”进行线程化,即。如果他们从未完成,则不会对应用程序或提出请求的用户造成任何损失。如果任务很重要,那么必须通过一个可靠的机制来提交,以保证在发生故障时执行,如Asynchronous procedure execution中所示。
+1

ASP.NET MVC支持异步控制器(http://msdn.microsoft.com/zh-cn/library/ee728598.aspx ),但我认为他们不适合这种即忘即忘式的任务。 – 2011-05-02 20:15:03

+0

他们打算放弃呼叫。我并不是真的在意他们是否完成了,而是想合理地确信他们会这样做。 – Buildstarted 2011-05-02 20:30:22

4

在这种情况下,一个重要的事情是确保包含在任务内的代码包装在try/catch块中,否则在此线程中抛出的任何可能的异常都会传播。您还应该确保在这个长时间运行的任务中,您不访问任何Http Context成员,如请求,响应,会话...,因为您访问它们时可能不再提供它们。

+0

我只是通过手动抛出异常来测试,并没有看到它们冒泡。但是,当它不在asp.net中时,它确实会冒泡。 – Buildstarted 2011-05-02 20:27:18

0

使用new Thread而不是Task.Factory.StartNewTask.Factory.StartNew使用线程池中的线程,并且如果您将有许多后台任务,则线程池将耗尽线程,并会降低您的Web应用程序。该请求将进行排队,并最终你的Web App将死:)

您可以测试你的背景工作使用Thread.CurrentThread.IsThreadPoolThread线程池执行。如果您变为True,则使用线程池。