如何确定我的所有线程何时完成执行?

Posted

技术标签:

【中文标题】如何确定我的所有线程何时完成执行?【英文标题】:How do I determine when all of my threads have finished executing? 【发布时间】:2011-10-25 23:23:44 【问题描述】:

我的架构可以从打包的二进制文件中读取数据包,根据数据包类型将每个数据包分配给单独的处理管道,然后将数据包重新组合到管道另一端的新文件中。每个管道包含类似于this one.的阻塞队列

在每个管道中的阻塞队列的每一侧都有一个线程,该线程运行一个循环,对数据包进行排队或出队。这些线程从控制器对象异步启动(即“即发即忘”风格)。此控制器对象有一个 Dictionary<int, ChannelPipeline> 集合,其中包含所有管道对象。

这是我的问题:我可以设置什么机制来告诉我所有管道何时完成处理?每个管道上都有一个EndOfData 属性;我是否必须在每个管道上不断轮询该属性,直到它们都读取true,还是有更好(即更有效)的方法?

【问题讨论】:

EndOfDataAutoResetEventWaitHandle.WaitAll() 成为你的朋友。 @Hans Passant:除非他有超过 64 个管道(或 WaitHandles),否则WaitAll() 似乎不允许同时等待更多句柄。 【参考方案1】:

如果知道管道总数可以考虑AutoResetEvent + 整数计数器

AutoResetEvent allThreadsDone = new AutoResetEvent(false);
int completedThreads;
int scheduledThreads;

基本上每个工作线程都会增加它使用的值Interlocked.Increment() 并设置事件以防它是最后一个线程:

Interlocked.Increment(ref completedThreads);
if (completedThreads == scheduledThreads)

    allThreadsDone.Set();

在监控线程中你只需这样做:

 allThreadsDone.WaitOne();
   // here is we know that all threads are finished

【讨论】:

不,这只会阻止线程完成。信号量的计数方式错误。 @Hans Passant :是的,我解决了这个问题,基本上完全删除了使用信号量的想法,因为看不到信号量已满/空的处理方式 补充一点,如果您使用的是 .NET 4.0,您还可以使用 CountdownEvent class,它似乎只提供了该功能。

以上是关于如何确定我的所有线程何时完成执行?的主要内容,如果未能解决你的问题,请参考以下文章

C#在遍历文件结构时如何判断所有线程或任务何时完成[重复]

如何在退出前重新附加线程或等待线程完成

如何在退出前安全地关闭所有线程[重复]

C# 线程异步处理

线程通信理论

Android:如何在所有后台线程完成后启用按钮