2

使用下面文章中的代码,我实现了一个自己的线程池:http: //www.developer.com/net/article.php/3783756

这就是我想要实现的目标:通过计时器触发,服务应每 5 秒查询一次数据库以执行新作业。Job 基本上只是有关需要使用参数运行的命令行程序的信息。

最多可以同时执行 50 个或更多这些程序。一个程序可以运行几秒钟、几分钟甚至几小时。服务需要始终控制这些程序,例如,它必须能够根据请求终止程序。

使用上面的 ThreadPool 实现,我开始对要执行的程序进行排队,并可以看到服务何时确实执行了它们。到目前为止没有问题。然而,这里的机制是这样工作的:

ThreadPool 创建一个工作线程并启动它。每当程序排队时,工作线程都会注意到这一点并调用一个委托,该委托实质上实例化了一个 System.Diagnostics.Process 对象并启动外部程序。然后线程完成了它的工作并且能够启动更多的程序。但是...当没有程序要启动时,空闲计时器会使线程管理器杀死线程,从而中断已启动的进程。

这不是我需要的。这里有人知道如何更好地处理我描述的场景吗?

4

3 回答 3

3

1)为什么这个进程中一个线程的死亡会导致另一个已启动进程的死亡?如果你回答了这个问题,你的问题就解决了。

2) 这看起来是一篇非常糟糕且相当幼稚的 ThreadPool 文章。查看Joe Duffy关于自定义线程池的系列(第 1部分、第 2部分和第 3 部分)。诸如此类的代码出奇地复杂,并且本身就是一个重大的维护负担。

3)(真正的答案)你为什么要使用线程池来做到这一点?您的线程池一次只使用一个线程,为什么不使用计时器并触发您的主线程呢?除了需要保持响应的 UI 之外,您的应用程序是否还执行其他操作?

摆脱线程池,没有必要,它让你的生活变得困难,而且线程池通常不是为托管长时间运行的任务而设计的。这就是单个线程的用途。如果您必须在单独的线程上触发计时器,只需创建一个线程来处理它并使用这个相同的线程来生成所有进程。然后,您可以在一个集中、合理的位置跟踪您的流程状态。:)

于 2009-06-09T11:19:19.603 回答
1

您确定线程池是处理此问题的最佳方式吗?为每个进程生成一个新线程,该线程大部分是空闲的,但在进程终止之前必须存在,这对我来说似乎是浪费线程。

我会用一个线程和一个进程字典来实现这一切。该线程将定期查询数据库和所有进程以查看需要执行哪些操作。

于 2009-06-09T11:19:21.710 回答
0

AFAIK,由 Process.Start 产生的进程将继续运行,即使调用 Process.Start 的线程退出。下面的代码说明了这一点。主程序退出后LongRunningApp.exe会继续运行:

static void Main(string[] args)
{
    Process p = new Process();
    ProcessStartInfo psi = new ProcessStartInfo(@"C:\LongRunningApp.exe");
    psi.CreateNoWindow = true;
    psi.UseShellExecute = false;
    p.StartInfo = psi;
    p.Start();
    Console.ReadLine();
}
于 2009-06-09T11:33:04.180 回答