2011-10-05 119 views
0

我嘗試使用多線程處理一些數據,我使用線程池生成的線程數量等於核心數量(限於.NET 2.0至3.5,因此無法使用TPL)。從線程池c更新進度條#

我的所有線程執行相同的功能,在我的數據的不同部分操作。

我的問題是我無法從線程池的線程更新進度條。找到解決方案,如調用和後臺工作人員,但不能真正瞭解如何使用它們,請幫助我如何使用它們。

我的代碼看起來像

private static float[] inpdat=new float[1000];//The input array to process 
//The spawned threads 
public void dowork(object o) 
{ 
    int np = (int)o; 
    for(int i=np;i<inpdat.length;i=i+Environment.ProcessorCount) 
    { 
     //do some processing 
     if(np==0) 
      { 
       //update progress bar here 
      } 
    } 
} 


    //The main thread 
    for (int npou = 0; npou < numproc; npou++) 
    { 
     resetEvents[npou] = new ManualResetEvent(false); 
     ThreadPool.QueueUserWorkItem(new WaitCallback(dowork), npou); 
     PetrelLogger.InfoOutputWindow("manual reset event set"); 
    } 

速度是最重要的,我如果跨線程調用佔用最小的時間,所以會是非常有益的。 謝謝

+2

「使用線程池生成等於內核數量的線程」 - 很少有人明確需要自行優化線程數。線程池是爲你設計的。 –

回答

0

有一點你可以做更新用戶控件,在你的情況進度條。 添加您的形式作爲輸入參數,或添加一些回調接口的結果,你的形式將實施:

interface IMyCallback 
{ 
    void Progress(int progress); 
} 

在形式上實現增加下面的代碼:

void Progress(int Progress) 
{ 
    if(this.InvokeRequired) 
    { 
     this.BeginInvoke(new ParametrizedThreadStart(Inv_Progress), Progress); 
    } 
    else 
    { 
     Inv_Progress(Progress); 
    } 
} 

void Inv_Progress(object obj) 
{ 
    int progress = obj as int; 
    // do your update progress bar work here 

} 

現在你可以做以下:

public void dowork(object o) 
{ 
    int np = (int)o; 
    for(int i=np;i<inpdat.length;i=i+Environment.ProcessorCount) 
    { 
     //do some processing 
     if(np==0) 
      { 
       myCallback.Progress(0); 
      } 
    } 
} 
1

下面是一個例子:

ThreadPool.QueueUserWorkItem(new WaitCallback(o => 
    { 
     // worker method implementation 
     ..... 
     progressBar1.Invoke(new MethodInvoker(() => progressBar1.Value = 20)); 
    })); 
+0

我的Algo和窗體屬於不同的類。不能刪除限制。 – user938972

+0

因此不能使用Invoke。任何解決方法? – user938972

+0

您的意思是說您沒有直接訪問ProgressBar控件,因爲它在不同的表單上,並且線程池在另一個類中調用? – A9S6

0

標準調用可能是最簡單的,您可以使用匿名代理來使其更清潔。

int n = 5; 
myProgressBar.Invoke(
    delegate 
    { 
     myProgressBar.Value = n; 
    } 
); 

請記住,在某些情況下(例如一個線程內循環使用該委託的距離),你可能需要聲明一個委託並傳遞價值成其爲一個參數。如果你不這樣做,你可能會與當地人發生奇怪的行爲。這也是使用匿名方法和Action類的情況。