【问题标题】:Why a thread is aborted in ASP.NET MVC (again)?为什么在 ASP.NET MVC 中(再次)中止线程?
【发布时间】:2010-04-28 16:04:22
【问题描述】:

这是我在控制器操作中所做的:

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

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

注意事项:

  • 我没有调用 Response.End 或 Response.Redirect - 抛出异常时甚至没有运行请求
  • 我尝试使用 ThreadPool 并得到相同的行为
  • 我知道在 ASP.NET 中运行线程有几个注意事项,但我现在不在乎

有什么建议吗?

【问题讨论】:

    标签: asp.net-mvc exception multithreading


    【解决方案1】:

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

    【讨论】:

    • 对不起,Spencer,但我已经说过我知道这是进行异步处理的次优方式,但在我的情况下没有其他方式。
    • 不幸的是,它不仅仅是次优的。它实际上是错误的,不是为这种用途而设计的。跟踪确定如何防止 IIS 终止长期运行的线程的方法可能是一项具有不可预见后果的黑客工作。如果没有其他方法,那么您的环境有问题。
    • 我同意你的看法。无论如何,我想出了一种方法来生成一个进程,我只需要验证它是否有效。
    • @Ryan - 哈哈,谢谢。我有时想知道有多少人认为这只是我的默认头像。
    【解决方案2】:

    这对你有帮助吗?

    "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

    【讨论】:

    • 我会试一试,但我怀疑行为会是一样的。此外,调用 EndInvoke 的需要使事情变得复杂,因为启动调用的原始线程是一个 ASP.NET ThreadPool 线程,因此它可能已经用于服务另一个请求。
    【解决方案3】:

    【讨论】:

    • 那将是显而易见的选择,但我似乎不知道如何以简单的方式向用户报告进度。最后,用户看到页面“卡住”了很长时间,这是不可接受的。无论如何我都必须使用 AJAX 调用,所以我想我会先尝试 Spencer 建议的流程解决方案。
    【解决方案4】:

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

    我觉得自己很笨。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      相关资源
      最近更新 更多