日期:2014-05-18  浏览次数:20853 次

C# 线程池 如何中继所有线程?
C# code

private void btnRun_Click(object sender, EventArgs e)
{
 ThreadPool.QueueUserWorkItem(new WaitCallback(function1));
 ThreadPool.QueueUserWorkItem(new WaitCallback(function2));
 ThreadPool.QueueUserWorkItem(new WaitCallback(function2));
 while (所有线程都工作完毕了?)
{
   // DOSTH……
 }
}
private void btnStop_Click(object sender, EventArgs e)
{
   //如何强行暂停所有线程?
   //如何强行中断或停止所有线程?
}


如题:3 个问题请达人赐教!!



------解决方案--------------------
1. 可以参考这个:http://hi.baidu.com/handboy/blog/item/1edd8d6dca811bf4431694da.html
2,3 ThreadPool中使用的是后台线程,当应用程序退出时自动中止所有后台线程,至于如何中断或暂停貌似没有提供操作方法,关注下此问题
------解决方案--------------------
线程池会根据当前系统特点对池内的线程进行优化处理。 总之使用线程池的作用就是减少创建和销毁线程的系统开销
一旦加入到线程池中就没有办法让它停止,除非任务执行完毕自动停止
------解决方案--------------------
第一个问题,看msdn:http://msdn.microsoft.com/zh-cn/library/system.threading.autoresetevent(v=vs.80).aspx

第二个、第三个问题,应该在你的所有程序设计一个统一的标志,然后程序中去适时查询这个标志。如果强行中断程序,只可能让系统(各种数据)状态混乱,没有好处。比如一个外科医生不可能在给病人刚刚开膛之后忽然想起该下班了然后直接走人了。
------解决方案--------------------
由于有太多的灾难性事件,所以.net中把那些强行suspend、强行stop的功能废弃了。你应该在业务层面自己设计并发程序的相互通知机制。
------解决方案--------------------
我给你解释一下msdn上的那个例子。一个计算需要分成四个程序并行计算:CalculateBase、CalculateFirstTerm、CalculateSecondTerm、CalculateThirdTerm。

方法Result开始时,首先把这个任务注册到系统线程池中。然后它等待autoEvents这个集合中的3个标志(表示后三个任务是否完成)全都变为true。然后返回后三个任务的结果的合计。

其中,manualEvent.Reset();这一句可以放在Result方法的最后,也可以放在最前边。主要是为manualEvent设置初始值(或者是重新设置初始值)使用。

那四个任务虽然并行执行,但是后三个任务全都有一行“manualEvent.WaitOne();”语句,等待它变为true时才继续执行。而只有第一个任务是执行“manualEvent.Set();”语句,让这个信号变为true。所以也就是后三个任务会一直阻塞到第一个任务发出这个信号,然后并行执行。

同时后三个任务每一个都有一条“autoEvents[0].Set();”语句,让autoEvents集合中相对于自己的那个信号变为true。


ManualResetEvent 就相当于处女,一旦打开了就不再自动关闭(于是之后的人可以长驱直入)。而AutoResetEvent就相当于地铁入口的检票机,一旦打开了只允许一个人通过,之后立刻重新关闭。
------解决方案--------------------
探讨
我给你解释一下msdn上的那个例子。一个计算需要分成四个程序并行计算:CalculateBase、CalculateFirstTerm、CalculateSecondTerm、CalculateThirdTerm。

方法Result开始时,首先把这个任务注册到系统线程池中。然后它等待autoEvents这个集合中的3个标志(表示后三个任务是否完成)全都变为true。然后返回后三个任务的结果的……