代码之家  ›  专栏  ›  技术社区  ›  Chris

看看C/ASP.NET线程终止时会发生什么,以及如何解决问题

  •  3
  • Chris  · 技术社区  · 14 年前

    我正在一个ASP.NET网站上工作,该网站在某些请求上运行非常长的缓存过程。我想知道,如果在代码如何处理执行超时的情况下,执行超时仍然在运行,那么会发生什么。

    特别是我想知道一些事情,比如代码是否在try/finally块中,finally是否仍然运行?

    另外,我不确定是否要终止缓存,即使缓存持续这么长时间,是否有一种方法可以生成新的线程等,我可以绕过这个执行超时?我认为立即返回用户并说“正在进行缓存构建”比让他们超时要好得多。我最近开始使用一些锁定代码,以确保一次只生成一个缓存,但我正在考虑扩展此代码以使其失去同步。

    我还没有真正玩过创建线程,像我自己,所以不确定它们是如何工作的,特别是在与ASP.NET交互方面。例如,如果启动它的父线程被终止,会对生成的线程有任何影响吗?

    我知道这里有很多不同的问题,如果这被认为是最好的,我可以把它们分开,但它们似乎都在一起…不过,我将尝试总结以下问题:

    1. 如果线程在try块中被ASP.NET终止,则仍将执行finally块吗
    2. 新创建的线程是否与原始线程具有相同的超时?
    3. 新创建的线程会与创建它们的父线程同时死亡吗?
    4. 一般来说,在ASP.NET站点上执行长时间运行的后台进程的最佳方法是什么?

    抱歉,我从来没有真正玩过线,它们仍然让我有点害怕(我的大脑说它们是 坚硬的 )我可能会测试很多tehse问题的答案,但我对自己的测试没有足够的信心。:)

    编辑添加:

    针对资本G:

    我遇到的问题是,ASP.NET执行超时当前设置为1小时,这对于我估计的某些进程来说并不总是足够长的。我在锁中放了一些东西,以防止不止一个人触发这些长过程,我担心锁可能不会被释放(我猜,如果最终块不总是运行,可能会发生这种情况)。

    您对ASP.NET中不运行长进程的评论是我考虑将它们移动到其他线程而不是阻塞请求线程的原因,但我不知道这是否仍然算作在您所说的糟糕的ASP.NET体系结构中运行。

    代码实际上不是我的,所以我不允许(也不确定我是否完全理解它)将它重新编写成一个服务,尽管这肯定是它最适合使用的地方。

    在这种情况下(关于ASP.NET中长时间运行的进程的注释),使用BackgroundWorker进程进行可能需要一个小时的工作是可行的。然后我会让请求返回一个“缓存正在构建”页面,直到它完成,然后返回到正常服务…这是一个噩梦,但它是我的工作,所以我必须找到一个方法来改善它。:)

    2 回复  |  直到 14 年前
        1
  •  1
  •   Capital G    14 年前
    1. 有趣的问题,刚刚测试过,不,它不能保证在finally块中执行代码,如果一个线程被中止,它可以在处理过程中的任何一点停止。您可以设计一些健全性检查和其他机制来处理特殊的清理例程等等,但是它也与您的线程处理有关。

    2. 不一定,这取决于如何实现线程。如果您自己处理线程,那么您可以很容易地进入这样的情况:当父线程的子线程仍在处理时,父线程被终止,您通常希望在结束子线程的父线程中进行一些清理。有些物品可能也会为你做很多这样的事情,所以说一种或另一种方式是很难的。至少不要假设这一点。

    3. 不,不一定,至少不要假定这一点,再次与您的设计有关,无论是您自己进行线程处理,还是使用更高级别的线程对象/模式。不管怎样,我决不会这么想。

    4. 我不建议在ASP.NET体系结构中长时间运行进程,除非它在典型的超时时间内,如果是10-20秒,可以,但是如果是分钟,不可以,原因是ASP.NET中的资源使用情况,而且对用户来说非常糟糕。也就是说,您可以执行异步操作,将工作交给服务器,然后在处理完成后返回给用户(这对于10-20多个进程来说是很好的),可以给用户一点动画,或者不让他们的浏览器停留很长时间等待发生的任何事情。将要发生的服务器。

    如果是一个长时间运行的进程,则需要30-60s+以上的时间,除非由于进程的性质必须在ASP.NET中完成,否则我建议将其移动到Windows服务,并在需要时以某种方式安排它。

    注意:线程处理可能很复杂,这并不是说你必须非常清楚自己在做什么,这需要对线程是什么以及它们是如何工作的有一个明确的了解,我不是专家,但我也不是完全的新手,我会告诉你,在大多数情况下,即使在线程处理的时候,你也不需要进入线程处理的领域。似乎是这样的,但是如果必须这样做,我建议在为了进行批处理等目的而简化BackgroundWorker对象时查看它们(老实说,对于许多确实需要线程的情况,这通常是一个非常简单的解决方案)。

    http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

        2
  •  1
  •   Kangkan    14 年前

    在网页后面启动耗时长的进程;它不应影响ASP.NET执行超时;应释放用户页;在锁定状态下运行请求等。所有这些情况都指向使用异步服务。在我所构建的其中一个产品中,使用服务来处理这些场景。该服务公开了一些要初始化的异步方法。可以使用其他方法查询进度状态。每个请求都有一些ID,并且不会触发重复的请求。即使用户注销,进度也会继续。用户稍后可以看到结果。

    如果您已经看过这些选项,请告诉我是否有任何问题。或者如果你还没有朝这个方向看,请朝这个方向看。如需任何帮助,请发送您的评论。