2011-06-09 36 views
6

在贏窗體應用程序,我有螺紋的一個數組,啓動這樣的:確保所有線程退出

bool stop = false; 
Thread[] threads = new Thread[10]; 

for (int i = 0; i < threads.Length; i++) 
    threads[i] = new Thread(new ThreadStart(Job)); 

// How to make sure all threads have exited, when the boolean = false 

void Job() 
{ 
    while (!stop) 
     // Do something 
} 

現在,如果用戶按STOP,爲stop布爾值設置爲true,那麼線程一個接一個退出Job方法。我如何確保所有線程退出?

注意:我需要傳統線程爲我的情況和TaskLibrary不符合我的情況。

回答

4

您是否想過使用BackgroundWorkers來代替?你說的是「傳統線索」..我不完全確定你的意思,所以我不知道這是否是一個有效的建議,但在這種情況下,無論如何,如果Join()不能解決你的問題

BackgroundWorker[] workers = new BackgroundWorker[10]; 
bool allThreadsDone = false; 

// initialize BackgroundWorkers 
for (int i = 0; i < 10; i++) 
{ 
     workers[i] = new BackgroundWorker(); 
     workers[i].WorkerSupportsCancellation = true; 
     workers[i].RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
     workers[i].DoWork += new DoWorkEventHandler(AlgorithmsUI_DoWork); 
     workers[i].RunWorkerAsync(); 
} 

// thread entry point..DoWork is fired when RunWorkerAsync is called 
void AlgorithmsUI_DoWork(object sender, DoWorkEventArgs e) 
{ 
     while (!stop) 
      // do something   
} 

// this event is fired when the BGW finishes execution 
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    bool threadsStillRunning = false; 
    foreach (BackgroundWorker worker in workers) 
    { 
     if (worker.IsBusy) 
     { 
      threadsStillRunning = true; 
      break; 
     } 
    } 
    if (!threadsStillRunning) 
     allThreadsDone = true; 
} 

protected override OnFormClosing(FormClosingEventArgs e) 
{ 
     if (!allThreadsDone) 
     { 
       e.Cancel = true; 
       MessageaBox.Show("Threads still running!"); 
     } 
} 

如果任何線程仍在運行,這應該阻止您的表單關閉。

7

使用Join方法檢查是否所有線程都已停止。

foreach (var t in threads) 
{ 
    t.Join(); 
} 
+0

把這段代碼放在哪裏?這是一個勝利形式的應用程序,UI線程在創建新線程後發佈。 – Xaqron 2011-06-09 02:35:39

+0

如果UI已經發布,那麼爲什麼要擔心?但嚴重的是,我會將它放在處理按下停止按鈕的方法中。 – 2011-06-09 02:39:32

+0

我想禁止程序退出,直到所有線程退出。如果用戶關閉主窗體並且任務管理器中有一些活動線程,用戶覺得應用程序失敗(儘管所有線程都會在一段時間後退出) – Xaqron 2011-06-09 02:50:19

1

我不知道如果這是你在找什麼,但這裏是我在.NET 3.0中使用回一個簡單的解決方案,以確保大,但確定性的線程數繼續之前已經完成:

全球:

AutoResetEvent threadPoolComplete = new AutoResetEvent(false); 
static int numThreadsToRun; 

當您激活線程:

numThreadsToRun = [number of threads]; 
[start your threads]; 
threadPoolComplete.WaitOne(); 

在每個線程的代碼末尾:

if (Interlocked.Decrement(ref numThreadsToRun) == 0) 
{ 
    threadPoolComplete.Set(); 
} 
+0

+這是非勝利形式類似任務的一個很好的例子。對於win表格,正如'alexD'所述,異步背景工作者更容易實現。 – Xaqron 2011-06-09 21:25:58