共有98条记录等待处理,但每次只允许开10个线程来处理,需要10次才处理完,请问怎么做?
用线程池好像不实现这样的灵活控制。大致设想如下,但是不行。int[] param = new int[98]; //共有98个记录,每个记录均为整数值,但并不连续
int ThreadNum = 10; //每次只开10个线程
j = 0; //记录数组的顺序号
for (i=0;i<ThreadNum;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Startscan),param[j]);
j++
}
public void Startscan(Object state)
{
Int32 id = (Int32) state;
//对param[j]的处理程序
}
用线程池好像不实现这样的灵活控制。大致设想如下,但是不行。int[] param = new int[98]; //共有98个记录,每个记录均为整数值,但并不连续
int ThreadNum = 10; //每次只开10个线程
j = 0; //记录数组的顺序号
for (i=0;i<ThreadNum;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Startscan),param[j]);
j++
}
public void Startscan(Object state)
{
Int32 id = (Int32) state;
//对param[j]的处理程序
}
//Define a class
public class RecordArray
{
private int[] nRecordArray;
private int nCurrent = -1;
public RecordArray( int[] Records )
{
nRecordArray = Records;
if( nRecordArray != null && nRecordArray.Length > 0 )
nCurrent = 0;
} public bool GetCurrent( out int RecordID )
{
RecordID = -1;
int nPosition;
lock( nRecordArray )
{
if( nCurrent < nRecordArray.Length )
{
nPosition = nCurrent;
nCurrent++;
}
else
nPosition = -1;
}
if( nPosition >= 0 )
{
RecordID = nRecordArray[nPosition];
return true;
}
else
return false;
}
}//Create threads
rec = new RecordArray( yourIntArray );//Init array hereint ThreadNum = 10; //每次只开10个线程
for (i=0;i<ThreadNum;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Startscan),null);
}private RecordArray rec;public void Startscan(Object state)
{
int nRecordID;
while( rec.GetCurrent( out nRecordID ) )
{
//Operate record with record ID info
}
}
private void button1_Click(object sender, System.EventArgs e)
{
int ThreadNum = 2; //每次只开 ThreadNum 个线程
Thread[] t = new Thread[ThreadNum];
int RecoNum = 4; //要处理的记录有 RecoNum 个
int[] RecoData = new int[RecoNum]; //要处理的数据 RecoData 以数组形式存放
int PageNum = 0; //将所有记录分为 PageNum 批来处理
int k = 0; //记录指针
if(RecoNum % ThreadNum == 0)
{
PageNum = RecoNum / ThreadNum;
}
else
{
PageNum = RecoNum / ThreadNum + 1;
}
for(int i = 0; i < PageNum; i ++) //分 PageNum 页来处理数据
{
for(int j = 0; j < ThreadNum; j ++) //调用 ThreadNum 个线程来处理
{
//MessageBox.Show(RecoData[k].ToString()); //处理 RecoNum 中的第 k 个记录
k ++; //指向数组中的下一条记录
t[i] = new Thread(new ThreadStart(GenerateNum));
t[i].Priority = System.Threading.ThreadPriority.BelowNormal;
t[i].IsBackground = true;
t[i].Start();
}
}
}
public void GenerateNum()
{
}
一、运行后,切换到其它窗口再回到现有窗口,为什么会出现假死状态?
二、如何使用“阻塞队列方式”来改写与此类似功能的多线程?谢谢。private static int ThreadCount = 0;
private void button1_Click(object sender, System.EventArgs e)
{
int RecoNum = 97; //被处理的记录有 RecoNum 个
int[] RecoData = new int[RecoNum]; //被处理的数据 RecoData 以数组形式存放
int p = 0; //存放被处理的数据指针
int ThreadNum = 13; //每次只开 ThreadNum 个线程
Thread[] t = new Thread[ThreadNum]; //初始化线程数组
int PageNum = 0; //将所有记录分为 PageNum 批来处理
if(RecoNum % ThreadNum == 0)//如果要处理的记录总数 RecoNum 恰好分成 PageNum 页(即分为 PageNum 批来处理)
{
PageNum = RecoNum / ThreadNum; //得页数,即外循环数
}
else
{
PageNum = RecoNum / ThreadNum + 1; //如果要处理的记录总数 RecoNum 恰好分成 PageNum 页还有余数则加1页
}
int k = 0; //存放总的循环次数
for(int i = 0; i < PageNum; i ++) //分 PageNum 页来处理数据
{
for(int j = 0; j < ThreadNum; j ++)//调用 ThreadNum 个线程来处理
{
if( k < RecoNum ) //如果总的循环次数小于被处理数据记录的个数才启动线程,考虑到分页时为非整时
{
ThreadCount ++;//记录当前正在处理的线程数量
subClassGetData x = new subClassGetData(p,t[j]);
t[j] = new Thread(new ThreadStart(x.ThreadGetData));
t[j].Priority = ThreadPriority.BelowNormal;//优先级定义为中下
t[j].IsBackground = true;
t[j].Name = "线程" + i + "" + j;
t[j].Start();
this.statusBar1.Text += t[j].Name + "." + k + "-";
while(ThreadCount != 0 && ThreadCount % ThreadNum == 0)//如果当前线程数与限定的线程数相等,则等待上次所有线程结束;ThreadCount == 0时表示当前没有线程的运行
{
Thread.Sleep(1000);
}
}
p ++; //指向数组中的下一条记录
k ++; //总的循环次数加1
}
}
statusBar1.Text = "所有线程已经结束!";
}
private class subClassGetData
{
protected int id = 0;
protected Thread th = null;
public subClassGetData(int p,object t)
{
id = p;
th = (Thread) t;
}
public void ThreadGetData()
{
Thread.Sleep(1000); //用Sleep来代替要处理数据(id)的过程
ThreadCount --; //将当前线程计数器减一
th.Abort(); //结束当前线程
}
}
rec = new RecordArray(yourIntArray);//Init array hereint ThreadNum = 10; //每次只开10个线程
for (int i=0;i<ThreadNum;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(StartScan),null);
}
public void Startscan(Object state)
{
int nRecordID;
while( rec.GetCurrent( out nRecordID ) )
{
//Operate record with record ID info
Thread.Sleep( 20 );
}
}这方面你可以参看
http://blog.csdn.net/Knight94/archive/2006/08/24/1111267.aspx
使用多线程加载多个Xml文件到TreeView控件
http://blog.csdn.net/zhzuo/archive/2004/06/10/22037.aspx编写多线程网络检测程序的简单实现
http://blog.csdn.net/zhzuo/archive/2004/07/08/37262.aspx