1、用于同步 在多线程(并发)或异步运行的程序的时候,我们常会这样做:
using System;
using System.Threading;
namespace ThreadPoolTest
{
class Program
{
private const int NumThreads = 5;
private static int[] inputArray;
private static double[] resultArray;
private static ManualResetEvent[] resetEvents;
private static void Main(string[] args)
{
inputArray = new int[NumThreads];
resultArray = new double[NumThreads];
resetEvents = new ManualResetEvent[NumThreads];
Random rand = new Random();
for (int s = 0; s < NumThreads; s++)
{
inputArray[s] = rand.Next(1,5000000);
resetEvents[s] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), (object)s);
}
Console.WriteLine("Waiting...");
WaitHandle.WaitAll(resetEvents);
Console.WriteLine("And the answers are: ");
for (int i = 0; i < NumThreads; i++)
Console.WriteLine(inputArray[i] + " -> " + resultArray[i]);
}
private static void DoWork(object o)
{
int index = (int)o;
for (int i = 1; i < inputArray[index]; i++)
resultArray[index] += 1.0 / (i * (i + 1));
resetEvents[index].Set();
}
}
}
但是,现在的问题是当ManualResetEvent数组的元素个数超过(>)64时,就会报如标题所示的异常(System.NotSupportedException: WaitHandle 的数目必须少于或等于 64 个)。 如何解决:
2、解决问题
方法一、设置计数标示,当完成我们线程数激发完成事件的响应标志。
using System;
using System.Threading;
namespace ThreadPoolTest
{
class Program
{
private static int _numerOfThreadsNotYetCompleted = 100;
private static ManualResetEvent _doneEvent = new ManualResetEvent(false);
private static void Main(string[] args)
{
for (int threadNumber = 0; threadNumber < 100; threadNumber++)
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork),
(object)threadNumber);
_doneEvent.WaitOne();
Console.WriteLine("All done.");
}
private static void DoWork(object o)
{
try
{
Console.WriteLine("Thread number: {0}", (int)o);
}
finally
{
if (Interlocked.Decrement(ref _numerOfThreadsNotYetCompleted) == 0)
_doneEvent.Set();
}
}
}
}
参考:http://www.codeproject.com/Articles/142341/Solved-The-number-of-WaitHandles-must-be-less-than
方法二、还用ManualResetEvent resetEvents = new ManualResetEvent[NumThreads]; 只不过对线程数分组,每组不超过64个。循环组数。
方法三、.NET4.0中可以通过 CountdownEvent 类解决。具体参见http://msdn.microsoft.com/en-us/library/system.threading.countdownevent.aspx
----------------------------------------------------------
over!