限制要执行的Backgroundworkers的数量

时间:2013-10-14 06:23:07

标签: c# multithreading datagridview backgroundworker

我正在使用多个backgroundworker来执行通过网络连接的过程。根据{{​​1}}中的行数,它获取每个行值并通过另一个执行长过程的类方法。这里我使用for循环来启动backgroundworker,所以问题是当进程开始时,基于datagridview行的数量,更多的后台工作者开始运行。但我想限制这一点。例如,如果我有50行,我只想一次执行5个后台工作者。在那5个完成任务之后,接下来的5个必须开始。那么如何限制呢?

我使用了以下代码:

datagridview

但是当我开始这个过程时,当时所有的背景工作者都开始了这项任务。任何人都可以帮助我吗?

提前致谢..

1 个答案:

答案 0 :(得分:2)

你要做的事情并不完全清楚。您的click方法为每个数据行启动一个新的BackgroundWorker,但是您的DoWork处理程序也会为每一行执行内部循环。很混乱。我认为你想要的是启动Max_Threads工人,让他们合作处理行。

您在增加threadNumber时遇到问题。增量不是原子操作,因此有可能两个并行递增它的线程最终会相互踩踏。您需要同步对该访问权限的访问,可能是使用Interlocked.Increment

我认为你想要做的是:

int threadNumber;
private void button1_Click(object sender, EventArgs e)
{
    threadNumber = -1;
    // Start Max_Threads workers
    for(int i=0; i<Max_Threads; i++)
    {
        var bs = new Backgroundworker();
        bs.DoWork += new DoWorkEventHandler(bs_DoWork);
        bs.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bs_Completed);
        bs.WorkerSupportCancellation = true;
        bs.RunWorkerAsync();
    } 
}

private void bs_DoWork(object sender, DoWorkEventArgs e)
{
    // Process items until cancellation requested, or until end of list
    while(!bs.CancellationPending)
    {
        int rowNumber = Interlocked.Increment(ref threadNumber);
        if (rowNumber >= datagridview1.Rows.Count)
        {
             break;
        }
        Webmethod obj = new webmethod();
        obj.Callmethod(rowNumber); // this takes long time to perform
    }
}