我正在开发一个ASP.NET网站,在某些请求中会运行一个非常冗长的缓存过程。我想知道如果在代码处理它的情况下它仍在运行时达到执行超时会发生什么。
特别是我想知道如果代码是在try / finally块的尝试中,最终仍然会运行吗?
另外,鉴于我不确定我是否希望缓存终止,即使它继续进行那么长时间有产生新线程等的方法,我可以绕过这个执行超时?我认为立即返回用户说“正在进行缓存构建”而不是让它们超时会更好。我最近开始玩一些锁定代码,以确保一次只发生一个缓存构建,但我正在考虑扩展它以使其失去同步。
我并没有真正使用像我这样的创建线程,所以我不确定它们是如何工作的,特别是在与ASP.NET交互方面。例如,如果启动它的父线程终止将对生成的线程产生任何影响吗?
我知道这里有很多不同的问题,如果这被认为是最好的,我可以将它们分开,但它们似乎都在一起......我会尝试总结这些问题:
对于一些无聊的问题我很抱歉,我从未真正玩过线程,他们仍然有点恐吓我(我的大脑说他们很难)。我可以测试很多问题的答案,但我对自己的测试不够自信。 :)
编辑以添加:
回应Capital G:
我遇到的问题是ASp.NET执行超时当前设置为一小时,这对于我认为的某些进程来说并不总是足够长。我已经把一些东西放进了锁中,以防止不止一个人引发这些长进程,我担心锁可能不会被释放(如果最终阻止并不总是运行,我猜可能会发生)。
你对ASP.NET中没有运行长进程的评论是我考虑将它们移动到其他线程而不是阻塞请求线程的原因,但我不知道这是否仍然算作在ASP.NET体系结构中运行你说的很糟糕。
代码实际上不是我的,所以我不被允许(并且不确定我100%理解它)将它重新编写成服务,尽管这肯定是它最适合居住的地方。
在这种情况下使用BackgroundWorker进程可能需要花费一个小时的时间(对于ASP.NET中长时间运行的进程的注释)。然后我会请求返回一个“缓存正在构建”页面,直到它完成,然后回到正常服务...这有点噩梦,但它的工作,所以我必须找到一种方法来改善它。 :)
答案 0 :(得分:1)
有趣的问题,刚刚测试过,并且不能保证在finally块中执行代码,如果线程被中止,它可能会在处理过程中的任何一点停止。您可以设计一些健全性检查和其他机制来处理特殊的清理程序等,但它也与您的线程处理有很大关系。
不一定,这取决于您实现线程的方式。如果你自己使用线程,那么你可以很容易地进入父线程被杀死的情况,而它的子线程仍处于处理状态,你通常想在父线程中做一些清理,也就是结束子线程。有些物品可能会为你做很多事情,所以说这种方式很难。永远不要假设这一点。
不,不一定,不要至少假设这一点,再次与您的设计有关,以及您是自己进行穿线还是使用更高级别的线程对象/模式。无论如何我都不会这么想。
我不推荐在ASP.NET体系结构中长时间运行的进程,除非它在典型的超时时间内,如果它是10-20秒可以,但是如果它是几分钟,不是,原因是ASP.NET中的资源使用这对用户来说非常糟糕。也就是说,您可以执行异步操作,将工作交给服务器,然后在处理完成后返回给用户(这对于那些10-20s +进程非常有用),可以给用户一点点动画或其他方式没有让他们的浏览器长时间等待服务器上发生的任何事情发生。
如果这是一个长时间运行的过程,需要超过30-60s +的事情,除非由于进程的性质而绝对必须在ASP.NET中完成,我建议将其移至Windows服务并安排它以某种方式在需要时发生。
注意:线程可能很复杂,并不是因为你必须非常了解自己在做什么,这需要牢固地了解线程是什么以及它们是如何工作的,我不是专家,但我也不是全新的,我会告诉你,在大多数情况下你不需要进入线程领域,即使看起来像你做的那样,但如果你必须这样做,我会建议调查BackgroundWorker对象因为它们被简化以进行批量处理等(诚实地,对于许多需要线程的情况,这通常是一个非常简单的解决方案)。
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
答案 1 :(得分:1)
在网页后面启动漫长或耗时的流程;它不应该超出ASP.NET执行时间;应该释放用户页面;在锁定等情况下运行请求。所有这些情况都指向使用异步服务。在我构建的其中一个产品中,使用了针对此类方案的服务。该服务公开了一些异步方法来启动。可以使用其他方法查询进度状态。每个请求都被赋予一些id,并且不会发出任何重复请求。即使用户退出,进度也会继续。用户可以在以后查看结果。
如果您已经查看了这些选项,请告诉我是否有任何问题。或者如果你还没有朝这个方向看,请按照这种方式进行。如需任何帮助,请发送您的意见。