限制要执行的后台工作进程数
本文关键字:工作 进程 后台 执行 | 更新日期: 2023-09-27 18:35:25
我正在使用多个backgroundworker
来执行通过网络连接的过程。根据datagridview
中的行数,它获取每一行值,并通过另一个执行长过程的类方法。在这里,我使用 for 循环来启动后台工作线程,所以问题是进程何时启动,基于 datagridview
行数,更多的后台工作线程开始运行。但我想限制这一点.例如,如果我有 50 行,我只想一次执行 5 个后台工作线程。在这 5 个完成任务后,下一个 5 个必须开始。那么如何限制这些呢?
我使用了以下代码:
Backgroundworker bs;
private void button1_Click(object sender, EventArgs e)
{
threadNumber = 0;
threadRunning = 0;
for(int i=0;i<datagridview1.Rows.Count;i++)
{
bs = new Backgroundworker();
bs.DoWork += new DoWorkEventHandler(bs_DoWork);
bs.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bs_Completed);
bs.WorkerSupportCancellation = true;
bs.RunWorkerAsync(i);
}
}
private void bs_DoWork(object sender, DoWorkEventArgs e)
{
int i = (int)e.Argument;
while(bs.CancellationPending !=true && threadNumber < datagridview1.Rows.Count)
{
lock (this)
{
for (int i = 0; i < Max_Threads - threadRunning; i++)
{
if (threadNumber < datagridview1.Rows.Count)
{
Webmethod obj = new webmethod();
obj.Callmethod(i); // this takes long time to perform
threadNumber +=1;
threadRunning +=1;
}
}
}
}
}
但是当我开始这个过程时,当时所有的后台工作人员都开始了任务。谁能帮我这个?
提前谢谢..
你想做什么并不完全清楚。单击 方法为每个数据行启动一个新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
}
}