2013-10-14 22 views
0

我使用多個backgroundworker來執行通過網絡連接的過程。根據datagridview中的行數,它獲取每個行值並通過執行長處理的另一個類方法。在這裏我使用for循環來啓動backgroundworker,所以問題是當進程啓動時,基於datagridview行的計數,更多的backgroundworkers開始運行。但我想限制這一點。例如,如果我有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; 
       } 
       } 
      } 
} 
} 

但是,當我啓動的過程中,當時所有的backgroundworkers啓動任務。任何人都可以幫助我嗎?

在此先感謝..

回答

2

你想要做的事情並不完全清楚。您的點擊方法會爲每個數據行啓動一個新的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 
    } 
} 
+0

感謝您的代碼,它的工作好。但我有一個疑問,在callmethod我給每個進程datagridview狀態味精,但它不顯示?你可以告訴我爲什麼它的發生? – yasmuru