2010-11-16 218 views
3
Monitor moni = new Monitor(); 
Thread t = new Thread(() => moni.CurrUsage(nics,200)); 
t.Start(); 

我開始了一個名爲「T」線程「Form1_Load的」函數內。我添加了一個按鈕。當點擊該按鈕時,線程't'應該停止執行,並用這些參數創建一個新線程。如何中止另一個函數內部啓動的線程?

Monitor moni = new Monitor(); 
Thread t = new Thread(() => moni.CurrUsage(nics,950)); 
t.Start(); 

我知道在Form_Load事件中,我可以使用

t.Abort(); 

回答

5

通過使t形式的會員,您可以稍後在按鈕單擊事件處理程序中引用它。

優美中止。 雖然t.Abort()完成了工作,但可能會在線程t中留下半處理數據。您可以通過線程t捕獲ThreadAbortException以優雅地結束處理。

當心的重疊。 第二個問題是當你的新線程已經啓動時,你的線程可能還沒有中止。調用t.Abort()之後,您可以通過調用t.Join()來阻止該操作。

希望這會有所幫助。

2

Thread t表單的私有成員。

public partial class MainForm : Form 
{ 
    private Thread t; 
} 
1

一種方法是使Thread t一個全局變量(的Form_Load以外的地方)。然後可以從該類中的任何方法訪問和修改它。

實例化線程,使用t = new Thread(....

中止線程之前,請確保它不爲空。

1

您需要在兩個需要訪問它的位置使Thread對象可訪問。 在這種情況下,使其成爲一個私人的變量會起作用。

例如

public class MyClass 
{ 
    private Thread MyThread 
    { 
    get; 
    set; 
    } 


    private void myfunc1() 
    { 
    MyThread = new Thread(() => moni.CurrUsage(nics,200)); 
    MyThread.Start(); 
    } 

    private void myfunc2() 
    { 
    MyThread.Abort(); 

    // I really need to wait until this thread has stopped... 
    MyThread.Join(); 
    } 

} 
+0

很好的解釋。我幫了我很多 – vishnu 2010-11-16 15:42:41

0

添加到已經給出答案:

注意.Join()將阻止當前的(UI)線程,讓你的應用程序沒有響應給用戶。

正如另一個看法:避免在您的顯示器類使用標誌退出如果可能的話,你在做任務用.Abort()。然後您仍然可以等待.Join(),但您可以完全控制後臺線程中的狀態。

public class Monitor 
{ 
    private bool _cancel = false; 

    public void Cancel() 
    { 
     _cancel = true; 
    } 

    public void CurrUsage(Nics nics, int n) 
    { 
     _cancel = false; 
     // ... 
     while (!_cancel) 
     { 
     // do some stuff 
     } 
    } 
} 

在表單

private Monitor _monitor { get; set; } 
private Thread _t; 
public void Button_Click(...) 
{ 
    _monitor.Cancel() 
    _t.Join()  // will return as your background thread has finished cleanly 
    _t = new Thread(() => _monitor.CurrUsage(nics,950)); 
    t.Start(); 
} 
0

正如其他人所指出的那樣,你爲了調用Abort需要的是線程(就像在.NET中任何其他對象)的引用。

然而

你應該認真考慮重新考慮這種做法。一般來說,呼籲Abort不鼓勵,因爲它不會給目標線程足夠的機會來達到停止點。雖然它有時適當(或唯一的選擇),它幾乎總是一個更好的主意,問目標線程停止(通常是通過volatile bool而不是迫使它這樣。

例如,

public class ThreadClass 
{ 
    private volatile bool stopRequested; 
    private Thread thread; 

    public void Start() 
    { 
     stopRequested = false; 
     thread = new Thread(ThreadMethod); 

     thread.Start(); 
    } 

    public void Stop() 
    { 
     stopRequested = true; 

     if(!thread.Join(5000)) thread.Abort(); // forcefully abort if not 
               // completed within 5 seconds 
    } 

    private void ThreadMethod() 
    { 

    } 
} 

然後你的代碼進入ThreadMethod在這個方法中,定期檢查stopRequested的值,如果它是真的,執行任何需要的清理(如果有的話)並優雅地返回到線程外,如果內容是循環,實踐是將檢查放在循環的開始處(假設循環足夠緊密)如果值爲true,則提前退出。確切的位置實際上取決於代碼,但總體思路是應該經常檢查它,以便線程在設置後很快退出,而不管發生什麼時候。

相關問題