代码之家  ›  专栏  ›  技术社区  ›  THX-1138

从线程池联接线程

  •  1
  • THX-1138  · 技术社区  · 14 年前

    我有30多个可以并行执行的任务。
    我为每个任务使用线程池。

    我需要一个线程同步句柄,当它的计数达到0时释放WaitOne。

    foo.StartWith(myTasks.Count);
    foreach (var task in myTasks) {
        ThreadPool.QueueUserWorkItem(state => { task(state); foo.Release(); });
    }
    foo.WaitOne();
    

    Semaphore 感觉不错,就是搞不懂怎么用在这里。

    3 回复  |  直到 14 年前
        1
  •  10
  •   Remus Rusanu    14 年前
    int running = myTasks.Count;
    AutoResetEvent done = new AutoResetEvent(false);
    foreach (var task in myTasks) {
        ThreadPool.QueueUserWorkItem(state => { 
        task(state); 
        if (0 == Interlocked.Decrement(ref running))
          done.Set ();
        });
    }
    done.WaitOne();
    

    使用C#4.0,您可以使用新的 CountdownEvent

        2
  •  0
  •   spender    14 年前

    Joe Duffy 写了一篇关于这类事情的好文章:

    CLR Inside Out: 9 Reusable Parallel Data Structures and Algorithms

    我把倒计时锁定得特别适合你的要求。

        3
  •  0
  •   YoniXw    8 年前

    根据这篇文章: Overview of Synchronization Primitives

    CountdownEvent Class

    或者类似的: Barrier (.NET Framework)

    对于较新版本,请使用TPL(任务并行库),对于此场景,此代码是相关的:

    // Create an ActionBlock<int> object that prints its input
    // and throws ArgumentOutOfRangeException if the input
    // is less than zero.
    var throwIfNegative = new ActionBlock<int>(n =>
    {
       Console.WriteLine("n = {0}", n);
       if (n < 0)
       {
          throw new ArgumentOutOfRangeException();
       }
    });
    
    // Post values to the block.
    throwIfNegative.Post(0);
    throwIfNegative.Post(-1);
    throwIfNegative.Post(1);
    throwIfNegative.Post(-2);
    throwIfNegative.Complete();
    
    // Wait for completion in a try/catch block.
    try
    {
       throwIfNegative.Completion.Wait();
    }
    catch (AggregateException ae)
    {
       // If an unhandled exception occurs during dataflow processing, all
       // exceptions are propagated through an AggregateException object.
       ae.Handle(e =>
       {
          Console.WriteLine("Encountered {0}: {1}", 
             e.GetType().Name, e.Message);
          return true;
       });
    }
    
    /* Output:
    n = 0
    n = -1
    Encountered ArgumentOutOfRangeException: Specified argument was out of the range
     of valid values.
    */
    

    https://msdn.microsoft.com/en-us/library/hh228603.aspx