Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从线程池连接线程_C#_Multithreading - Fatal编程技术网

C# 从线程池连接线程

C# 从线程池连接线程,c#,multithreading,C#,Multithreading,我有30多个可以并行执行的任务。 我为每个任务使用线程池。 但在所有任务完成之前,父函数不应返回 我需要一个线程同步句柄,当WaitOne的计数达到0时,它将释放WaitOne。 比如: foo.StartWith(myTasks.Count); foreach (var task in myTasks) { ThreadPool.QueueUserWorkItem(state => { task(state); foo.Release(); }); } foo.WaitOne()

我有30多个可以并行执行的任务。
我为每个任务使用线程池。
但在所有任务完成之前,父函数不应返回

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

foo.StartWith(myTasks.Count);
foreach (var task in myTasks) {
    ThreadPool.QueueUserWorkItem(state => { task(state); foo.Release(); });
}
foo.WaitOne();
Semaphore
感觉不错,只是不知道如何在这里应用它

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,你可以使用新的原语。

写了一篇关于这类东西的好文章:


我正在考虑倒计时闩锁,因为它特别适合您的要求。

根据本文:

C#具有此场景的内置类型CountDownEvent:

或者一个类似的例子:

对于较新版本,请使用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.
*/
//创建打印其输入的ActionBlock对象
//如果输入
//小于零。
var throwIfNegative=新动作块(n=>
{
WriteLine(“n={0}”,n);
if(n<0)
{
抛出新ArgumentOutOfRangeException();
}
});
//将值发布到块。
throwIfNegative.Post(0);
throwIfNegative.Post(-1);
throwIfNegative.Post(1);
throwIfNegative.Post(-2);
throwIfNegative.Complete();
//在try/catch块中等待完成。
尝试
{
throwIfNegative.Completion.Wait();
}
捕获(聚合异常ae)
{
//如果在数据流处理期间发生未处理的异常,则所有
//异常通过AggregateException对象传播。
ae.句柄(e=>
{
WriteLine(“遇到{0}:{1}”,
e、 GetType().Name,e.Message);
返回true;
});
}
/*输出:
n=0
n=-1
遇到ArgumentOutOfRangeException:指定的参数超出范围
有效值的定义。
*/

或4.0任务类,更好的捕鼠器。不要将此作为答案,因为它与您的问题相切,但如果您使用BeginInvoke而不是threadpool项开始这些任务,您可以从AysncResults中获取WaitHandles,并调用WaitAll。如果threadpool的优势超过了这一点,那么这不是一个很好的答案,但如果不是,那么它就值得一看。