为什么一个线程在ASP.NET MVC(再次)中被中止?

问题描述:

以下是我在一个控制器动作做:为什么一个线程在ASP.NET MVC(再次)中被中止?

  1. 创建并启动一个新的线程,做一个比较长的处理任务(平均约30秒,但可能是几分钟)
  2. 立即返回页面响应,以便用户知道处理已经开始(简单地说,具有用于轮询目的的任务ID的Json)。

在某个随机点引发ThreadAbortException异常,所以异步任务没有完成。每次都不会抛出异常,只是随机发生大约25%的时间。

注意要点:

  • 我没有打电话或到Response.End Response.Redirect的 - 没有,即使抛出异常的请求运行
  • 我尝试使用线程池和我同样的行为
  • 我知道ASP.NET运行的线程有几个注意事项,但我现在不

任何建议在乎吗?

的问题是,该应用程序是被回收。我完全知道,当发生这种情况时,所有线程都会中止,我没有想到应用程序会回收。原因是使用的异步进程更改了存储在应用程序根目录中的临时文件,并导致了回收。

我觉得哑巴。

问题是你不应该这样做。如果您需要在后台运行很长一段时间的任务,ASP.Net应该生成一个进程来处理它,或者将工作项添加到队列中以供Windows服务处理。

+0

对不起Spencer,但我已经说过,我知道这是做异步处理的次优方式,但在我的情况下没有别的办法。 – 2010-04-28 16:22:26

+0

不幸的是,它不是简单的次优。这实际上是错误的,并不是为这种使用而设计的。跟踪确定如何阻止IIS终止长时间运行的线程的方法很可能会是一种无法预料的后果。如果没有其他方式,那么你的环境出现问题。 – 2010-04-28 20:21:56

+0

我同意你的意见。无论如何,我想出了一种方法来产生一个过程,我只需要验证它的工作。 – 2010-04-29 05:20:37

这是否有帮助,因为你想开火并忘记。

"Delegates provide a method called BeginInvoke that allows us to call the delegate asychronously." 

http://hackingon.net/post/Asynchronous-fire-and-forget-method-calls-in-NET.aspx

+0

我会试一试,但我怀疑这种行为是一样的。此外,调用EndInvoke的需求会使事情复杂化,因为开始调用的原始线程是ASP.NET ThreadPool线程,所以它可能已经被用于服务另一个请求。 – 2010-04-29 05:27:32

+0

这将是明显的选择,但我似乎无法想象如何以简单的方式向用户报告进度。最终,用户看到页面长时间“卡住”,这是不可接受的。无论如何,我必须使用AJAX调用,所以我想我会先尝试Spencer建议的流程解决方案。 – 2010-04-29 05:25:25