共有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]的处理程序
}

解决方案 »

  1.   

    Sample code as follows:
    //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
    }
    }
      

  2.   

    我是这样写的,不知道下面的怎么完善了咯。
    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()
    {
    }
      

  3.   

    愚翁兄弟,经过思考,写成以下代码,但是有两个疑问:
    一、运行后,切换到其它窗口再回到现有窗口,为什么会出现假死状态?
    二、如何使用“阻塞队列方式”来改写与此类似功能的多线程?谢谢。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(); //结束当前线程
    }
    }
      

  4.   

    愚翁兄弟,在小数据量时,你的方法故然可行,但是一旦数据量很大的时候,程序一运行,CPU占用就会达到100%,然后程序就没有响应了,怎么解决?谢谢。int[] yourIntArray = new int[999999];
    rec = new RecordArray(yourIntArray);//Init array hereint ThreadNum = 10; //每次只开10个线程
    for (int i=0;i<ThreadNum;i++)
    {
    ThreadPool.QueueUserWorkItem(new WaitCallback(StartScan),null);
    }
      

  5.   

    to 程序一运行,CPU占用就会达到100%,然后程序就没有响应了,怎么解决?谢谢。加入Sleep语句
    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
      

  6.   

    类似的例子参考,
    使用多线程加载多个Xml文件到TreeView控件
    http://blog.csdn.net/zhzuo/archive/2004/06/10/22037.aspx编写多线程网络检测程序的简单实现
    http://blog.csdn.net/zhzuo/archive/2004/07/08/37262.aspx