多线程 - 等待所有线程发出信号

时间:2009-12-30 21:25:07

标签: c# multithreading clr wait waithandle

我有一些场景,我需要一个主线程等待,直到一组可能超过64个线程的每一个都完成了他们的工作,为此我写了下面的帮助器实用程序,(以避免{等待句柄的64个限制{ {1}})

WaitHandle.WaitAll()

但是,使用这个实用程序方法,每个waithandle只在数组中的每个前一个被检查后才被检查...所以它实际上是同步的,并且如果waithandles是autoResetEvent等待句柄(它清除为等待线程即将发布)

要解决此问题,我正在考虑将此代码更改为以下内容,但希望其他人检查并查看它是否可行,或者是否有人发现任何问题,或者可以提出更好的方法..

提前致谢:

    public static void WaitAll(WaitHandle[] handles)
    {
        if (handles == null)
            throw new ArgumentNullException("handles",
                "WaitHandle[] handles was null");
        foreach (WaitHandle wh in handles) wh.WaitOne();
    }

5 个答案:

答案 0 :(得分:3)

如果您知道有多少线程,则可以使用互锁减量。这就是我通常这样做的方式:

 {
 eventDone = new AutoResetEvent();
 totalCount = 128;
 for(0...128) {ThreadPool.QueueUserWorkItem(ThreadWorker, ...);}
 }

 void ThreadWorker(object state)
 try
 {
   ... work and more work
 }
 finally
 {
   int runningCount = Interlocked.Decrement(ref totalCount);
   if (0 == runningCount)
   {
     // This is the last thread, notify the waiters
     eventDone.Set();
   }
 }

实际上,大多数时候我甚至没有发出信号,而是调用回调继续从服务员继续进行处理。线程阻塞少,可扩展性更强。

我知道是不同的,可能不适用于你的情况(例如,如果某些thoe句柄不是线程,但I / O或事件,肯定不会工作),但它可能值得考虑这个。

答案 1 :(得分:2)

我不确定你究竟要做什么,但CountdownEvent(.NET 4.0)会从概念上解决你的问题吗?

答案 2 :(得分:1)

我不是C#或.NET程序员,但您可以使用在您的某个工作线程退出时发布的信号量。监视线程只需等待信号量 n 次,其中 n 是工作线程的数量。信号量传统上用于计算正在使用的资源,但它们可用于通过等待 n 次的相同信号量来计算完成的作业。

答案 3 :(得分:0)

当处理大量同步线程时,我更喜欢在启动线程时将每个线程的ManagedThreadId添加到Dictionary中,然后让每个线程调用一个回调例程,从而从Dictionary中删除垂死线程的id。 Dictionary的Count属性告诉您有多少个线程处于活动状态。使用键/值对的值侧保存UI线程可用于报告状态的信息。用锁包裹字典以保证安全。

答案 4 :(得分:-1)

ThreadPool.QueueUserWorkItem(o =>
{
    try
    {
        using (var h = (o as WaitHandle))
        { 
            if (!h.WaitOne(100000))
            {
                // Alert main thread of the timeout
            }
        }
    }
    finally
    {
        Interlocked.Decrement(ref actThreadCount);
    }
 }, wh);