1

考虑一个使用 sql server 数据库中的表来调度作业的大型应用程序,表中的每一行都标记有 queueID、methodName 和其他元数据。methodName 可以是本机 dot net 接口、旧版 com 本地接口、第 3 方 com 接口或第 3 方 Web 服务的 URI。

目前有一个处理每个 queueID 的 32 位后台 exe 家族。queueID 设置了每个作业可以运行多长时间的最大时间限制,如果超过时间限制,看门狗将终止进程。

我们希望将其移至 64 位环境并将多个后台 exe 进程合并到单个多线程 Windows 服务中。

问题是我们如何处理超过设定时间限制的工作终止。如果我们从单个 appDomain 主线程的任务并行库中为每个 queueID 分配一个任务,显然不能使用 net4.0 取消令牌,因为该线程可能运行 com 接口或第 3 方 Web 服务。如果 appDomain 看门狗任务调用 Thread.abort() 它可能会破坏整个 appDomain 并拆除所有任务线程我不清楚 Thread.Interrupt() 是否会在没有 appDomain 损坏的情况下可靠地取消线程。

那么有什么建议的技术来杀死一个超过时间限制的线程呢?

或者

我们是否只是让服务为每个 queueID 创建一个 AppDomain 然后执行 myAppDomain1.ExecuteAssembly("queueProcess.exe arg1") myAppDomain2.ExecuteAssembly("queueProcess.exe arg2") ...几乎与现在存在的拱门相同,但它是一个胜利控制 appDomains 和每个 queueProcess.exe 的服务,然后使用 tpl 线程池在每个 queueProcess.exe 的一组较小的池中运行作业,并且看门狗只执行 AppDomain?。当进程超过其时间时卸载限制

4

1 回答 1

1

您不能调用任意本机代码并使其干净地关闭。如果你杀死它的线程(如果你已经使用 CreateThread 启动了那个线程,这是可能的),你通常会泄漏内存、损坏数据、不释放锁、保持文件句柄打开等等。没有合作,这是行不通的。进程是处理这个问题的正确方法,因为它们可以随时被干净地杀死。

对于仅托管的任务,您可以安全地卸载 appdomain(ASP.NET 就是这样做的)。不要仅仅中止线程,因为它可能使全局结构处于不一致的状态。或者您可能会中止一个静态 ctor,这会使整个类永远无法使用(静态 ctor 不可重新启动)。

您可以有一个通用的主机进程,它通过命名管道获取其输入并运行您的任务。这样的过程可以是轻量级的。你可以随时杀死它。

于 2012-04-05T23:05:44.650 回答