前段时间有任务要用到线程池来解决一个问题,大概描述如下:
要对很多个订单(百万级别)进行处理,处理完毕后需要告诉客户端处理完毕并告之是否全部成功.
其实比较麻烦的就在第二点,试图用WaitHandle.WaitAll()却发现只支持64个Events.
小小地改造了一下这个函数,能同时支持无数个.


public static void WaitAll(WaitHandle[] waitHandles)
{
if (waitHandles == null)
throw new ArgumentNullException("handles");
foreach (WaitHandle wh in waitHandles)
{
if (!wh.WaitOne(_TimeOut, false))
{
throw new TimeoutException();
}
}
}
{
if (waitHandles == null)
throw new ArgumentNullException("handles");
foreach (WaitHandle wh in waitHandles)
{
if (!wh.WaitOne(_TimeOut, false))
{
throw new TimeoutException();
}
}
}
此后的任务就很easy了……
以下是Send.cs主要代码


1 ThreadPool.SetMaxThreads(_MaxThread, _MaxThread);
2 _totalCount = sendOrders.Rows.Count;
3 SendThread[] SendThreadArray = new SendThread[_totalCount];
4 ManualResetEvent[] doneEvents = new ManualResetEvent[_totalCount];
5 DateTime begin = DateTime.Now;
6 for (int i = 0; i < sendOrders.Rows.Count; i++)
7 {
8 doneEvents[i] = new ManualResetEvent(false);
9 SendThread _sendThread = new SendThread(sendOrders.Rows[i], doneEvents[i]);
10 ThreadPool.QueueUserWorkItem(_sendThread.sendThreadCallBack, i);
11 SendThreadArray[i] = _sendThread;
12 }
13
14 try
15 {
16 //等待所有线程结束
17 WaitAll(doneEvents);
18 }…………
2 _totalCount = sendOrders.Rows.Count;
3 SendThread[] SendThreadArray = new SendThread[_totalCount];
4 ManualResetEvent[] doneEvents = new ManualResetEvent[_totalCount];
5 DateTime begin = DateTime.Now;
6 for (int i = 0; i < sendOrders.Rows.Count; i++)
7 {
8 doneEvents[i] = new ManualResetEvent(false);
9 SendThread _sendThread = new SendThread(sendOrders.Rows[i], doneEvents[i]);
10 ThreadPool.QueueUserWorkItem(_sendThread.sendThreadCallBack, i);
11 SendThreadArray[i] = _sendThread;
12 }
13
14 try
15 {
16 //等待所有线程结束
17 WaitAll(doneEvents);
18 }…………
以下是SendThread.cs主要代码


public class SendThread
{
DataRow _orderInfo;
private ManualResetEvent _doneEvent;
public SendThread(DataRow OrderInfo, ManualResetEvent DoneEvent)
{
_orderInfo = OrderInfo;
_doneEvent = DoneEvent;
}
public void sendThreadCallBack(object threadContext)
{
// do sth.
_doneEvent.Set();
}
}
{
DataRow _orderInfo;
private ManualResetEvent _doneEvent;
public SendThread(DataRow OrderInfo, ManualResetEvent DoneEvent)
{
_orderInfo = OrderInfo;
_doneEvent = DoneEvent;
}
public void sendThreadCallBack(object threadContext)
{
// do sth.
_doneEvent.Set();
}
}
enjoy~