使用以下文章中的代码,我实现了一个自己的ThreadPool: http://www.developer.com/net/article.php/3783756
这是我想要实现的目标: 通过Timer触发,服务应每5秒查询一次数据库,以便执行新的作业。 Job基本上只是有关需要使用参数运行的命令行程序的信息。
这些程序中最多可以同时执行50个或更多。程序可以运行几秒钟,几分钟甚至几小时。该服务需要始终控制这些程序,例如它必须能够根据请求终止程序。
使用上面的ThreadPool实现,我开始对要执行的程序进行排队,并且可以看到服务确实执行它们的时间。到目前为止没问题。但是,这里的机制是这样的:
ThreadPool创建一个workerthread并启动它。每当程序排队时,workerthread都会注意到这一点并调用一个委托,该委托基本上实例化System.Diagnostics.Process对象并启动外部程序。然后该线程完成其工作,并将能够启动进一步的程序。但是......当没有程序启动时,空闲计时器会使线程管理器终止该线程,从而中断已经启动的进程。
这不是我需要的。这里有没有人有想法,如何更好地处理我描述的场景?
答案 0 :(得分:3)
1)为什么在这个过程中线程的死亡会导致另一个线程的死亡,启动过程?如果你回答这个问题,你就可以解决问题了。
2)这看起来像一个非常糟糕,相当天真的ThreadPool文章。查看自定义线程池(Joe Duffy's,part 1和part 2)上的part 3系列。诸如此类的代码令人惊讶地错综复杂,并且本身就存在巨大的维护负担。
3)(真正的答案)你为什么要用线程池来完成这个?你的线程池一次只使用一个线程,为什么不只是使用一个计时器并触发你的主线程?除了需要保持响应的UI之外,您的应用还能做其他事吗?
摆脱线程池,不需要它,它会让你的生活变得困难,并且线程池通常不是为承载长时间运行的任务而设计的。这就是个人线程的用途。如果必须在单独的线程上触发计时器,只需创建一个线程来处理它,并使用这个相同的线程来生成所有进程。然后,您可以在一个中央,合理的位置跟踪您的过程状态。 :)
答案 1 :(得分:1)
您确定线程池是处理此问题的最佳方式吗?为每个进程生成一个新线程,这个进程大部分都是空闲但必须存在,直到进程终止,这对我来说似乎是一个浪费。
我将使用单个线程和进程字典来实现所有这些。该线程将定期查询数据库和所有进程,以查看需要执行的操作。
答案 2 :(得分: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();
}