Reputation: 1186
I'm using multiple backgroundworker
to execute process of connecting through network . Based on the number of rows in datagridview
, it fetches each row values and passes through the another class method which perform long process. Here i'm using for loop to start the backgroundworker, so the problem is when the process starts, based on the count of datagridview
rows more backgroundworkers starts to run. But i want to limit this . For example , if i have 50 rows , i just wants to execute 5 backgroundworkers at a time. After those 5 finishes the task the next 5 has to start . So how to limit those ?
I have used following code :
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;
}
}
}
}
}
But when i start the process, at the time all the backgroundworkers starts the task . Can anyone help me in this ?
Thanks in advance..
Upvotes: 0
Views: 560
Reputation: 134015
What you're trying to do isn't entirely clear. Your click method starts a new BackgroundWorker
for each data row, but then your DoWork
handler also executes the inner loop for each row. Very confusing. I think what you want is to start Max_Threads
workers, and have them cooperate in processing the rows.
You have a problem with incrementing your threadNumber
. Increment is not an atomic operation, so it's possible that two threads incrementing it concurrently will end up stepping on each other. You need to synchronize access to that, probably by using Interlocked.Increment.
I think what you want to do is this:
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
}
}
Upvotes: 2