多线程分页法对数据操作
1 int pagesize = 10000; //每多少条数据一个线程 2 int pagenum;//线程数量 3 4 public void start() 5 { 6 try 7 { 8 List<test> testList = new List<test>();//数据集合 9 10 pagenum = getpage(testList.Count, pagesize);//根据数据量求出需要多少线程 11 ManualResetEvent[] events = new ManualResetEvent[pagenum]; 12 if (pagenum < 64) 13 { 14 for (int i = 0; i < pagenum; i++) 15 { 16 events[i] = new ManualResetEvent(false); 17 ThreadPool.SetMaxThreads(10, 10); 18 19 int si = i; 20 int ei = i + 1; 21 22 TestStart bllStart = new TestStart(events[si]); 23 ThreadPool.QueueUserWorkItem(delegate(object notUsed) { bllStart.ForList(si, ei, pagesize, pagenum, testList); }); 24 } 25 ManualResetEvent.WaitAll(events); 26 } 27 else 28 { 29 using (var countdown = new MutipleThreadResetEvent(pagenum)) 30 { 31 for (int i = 0; i < pagenum; i++) 32 { 33 34 int si = i; 35 events[si] = new ManualResetEvent(false); 36 int ei = i + 1; 37 ThreadPool.SetMaxThreads(5, 5); 38 ThreadPool.QueueUserWorkItem(delegate(object notUsed) 39 { 40 TestStart bllStart = new TestStart(events[si]); 41 bllStart.ForList(si, ei, pagesize, pagenum, testList, countdown); 42 }); 43 } 44 countdown.WaitAll(); 45 } 46 } 47 48 } 49 catch (Exception e) 50 { 51 52 53 } 54 } 55 56 57 public int getpage(int i, int j) 58 { 59 int count = 0; 60 int num1 = i % j; 61 if (num1 > 0) 62 { 63 count = (i / j) + 1; 64 if (i / j == 0 && i < j) 65 { 66 count = 1; 67 } 68 } 69 else 70 { 71 count = i / j; 72 } 73 return count; 74 } 75 76 77 78 public class TestStart 79 { 80 ManualResetEvent manualEvent; 81 public TestStart(ManualResetEvent manualEvent) 82 { 83 this.manualEvent = manualEvent; 84 } 85 86 public void ForList(int si, int ei, int pagesize, int pagesInThread, List<test> list) 87 { 88 try 89 { 90 si = si * pagesize; 91 if (ei == pagesInThread) //最后一个线程 92 { 93 //结束条数 94 ei = list.Count; 95 } 96 else 97 { 98 //结束条数 99 ei = ei * pagesize; 100 } 101 for (int i = si; i < ei; i++) 102 { 103 test item = list[i]; 104 105 //操作代码 106 } 107 } 108 catch (Exception e) 109 { 110 111 } 112 finally 113 { 114 manualEvent.Set(); 115 } 116 117 } 118 119 120 121 public void ForList(int si, int ei, int pagesize, int pagesInThread, List<test> list, object state) 122 { 123 MutipleThreadResetEvent countdown = state as MutipleThreadResetEvent; 124 try 125 { 126 si = si * pagesize; 127 if (ei == pagesInThread) //最后一个线程 128 { 129 //结束条数 130 ei = list.Count; 131 } 132 else 133 { 134 //结束条数 135 ei = ei * pagesize; 136 } 137 for (int i = si; i < ei; i++) 138 { 139 140 } 141 } 142 catch (Exception e) 143 { 144 145 } 146 finally 147 { 148 countdown.SetOne(); 149 } 150 151 } 152 }
线程数量大于64解决方案参考: http://www.cnblogs.com/charley_yang/archive/2010/11/13/1876626.html
/********************************************************************************
* Copyright © 2001 - 2010Comit. All Rights Reserved.
* 文件:MutipleThreadResetEvent.cs
* 作者:杨柳
* 日期:2010年11月13日
* 描述:封装 ManualResetEvent ,该类允许一次等待N(N>64)个事件执行完毕
*
* 解决问题:WaitHandle.WaitAll(evetlist)方法最大只能等待64个ManualResetEvent事件
* *********************************************************************************/
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading;
namespace
TestMutipleThreadRestEvent
{
/// <summary>
/// 封装ManualResetEvent
/// </summary>
public
class
MutipleThreadResetEvent : IDisposable
{
private
readonly
ManualResetEvent done;
private
readonly
int
total;
private
long
current;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="total">需要等待执行的线程总数</param>
public
MutipleThreadResetEvent(
int
total)
{
this
.total = total;
current = total;
done =
new
ManualResetEvent(
false
);
}
/// <summary>
/// 唤醒一个等待的线程
/// </summary>
public
void
SetOne()
{
// Interlocked 原子操作类 ,此处将计数器减1
if
(Interlocked.Decrement(
ref
current) == 0)
{
//当所以等待线程执行完毕时,唤醒等待的线程
done.Set();
}
}
/// <summary>
/// 等待所以线程执行完毕
/// </summary>
public
void
WaitAll()
{
done.WaitOne();
}
/// <summary>
/// 释放对象占用的空间
/// </summary>
public
void
Dispose()
{
((IDisposable)done).Dispose();
}
}
}