2014-09-30 52 views
1

我有我打電話裏面的Thread.Here是方法的方法..如何正確關閉線程在C#中

private System.Threading.Thread _thread; 
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false); 

private void DoWork() 
    { 
     while (!_shutdownEvent.WaitOne(0)) 
     { 
       //Business logic 
     } 
    } 

和現在,我在這裏啓動線程..

_thread = new Thread(DoWork); 
_thread.Start(); 

現在按我的要求,我想關閉並重新啓動Thread..For關閉和重新啓動我試圖此代碼..

_shutdownEvent.Set(); // trigger the thread to stop 
    _thread.Join(); 

但我瘦k這是不正確的方式來關閉線程並重新啓動它..

請幫我關閉並重新啓動線程在我的情況。 在此先感謝..

+0

您正在使用哪種.NET框架版本? – 2014-09-30 08:22:14

+0

@YuvalItzchakov .Net4.0 – 2014-09-30 08:23:00

+4

@shubhamHegdey在這種情況下,你可能會考慮使用TPL – decPL 2014-09-30 08:24:25

回答

3

我建議你看看到Task Parallel Library,這使得細粒度控制其執行和supports a cancellation mechanism通過CancellationToken結構:

下面是一個例子:

var tokenSource = new CancellationTokenSource(); 
CancellationToken ct = tokenSource.Token; 

var task = Task.Factory.StartNew(() => 
{ 
     // Were we already canceled? 
     ct.ThrowIfCancellationRequested(); 

     bool moreToDo = true; 
     while (moreToDo) 
     { 
      // Poll on this property if you have to do 
      // other cleanup before throwing. 
      if (ct.IsCancellationRequested) 
      { 
       // Clean up here, then... 
       ct.ThrowIfCancellationRequested(); 
      } 

     } 
    }, tokenSource.Token); // Pass same token to StartNew. 

tokenSource.Cancel(); 

關於「重新啓動線程」,您無法重新啓動給定的Task。你可以做的是看到它被取消(一個任務包含一個Status屬性,一旦你取消就會變成Canceled),如果是,則執行一個新的任務。

2

恩,試試現代的東西。

private Task DoWork(CancellationToken token) 
{ 
    while (!token.IsCancellationRequested) 
    { 
     // ... It would be nice if you could await something here. 
    } 

    return Task.FromResult(true); 
} 

然後,只是信號的CancellationToken

using (var cts = new CancellationTokenSource()) 
{ 
    await Task.WhenAny(
     DoWork(cts.Token), 
     SomeOtherWork()) 

    cts.Cancel(); 
} 
2

您目前正在等待線程結束的方式看起來很好 - 線程死亡時,他們跑出來的代碼,Join確保它已完成。

雖然您不能重新啓動線程,但您必須創建一個新線程。

我同意其他答案,你可能想看看可用的新技術,它們允許更具可讀性的代碼。

3

您應該儘量避免自己管理線程,並讓CLR爲您做到這一點。創建線程是最容易出錯的昂貴的錯誤活動。

FCL提供了可用於管理線程的類型。看看QueueUserWorkItem這將執行回調中給出的一些代碼。如果你只是想說「去做點什麼」,而且你不在乎何時/如果它完成了,而且它沒有任何回報價值,那麼這種方法很有效。如果您想查看返回值,並知道什麼時候完成,請使用tasks

我強烈推薦由Jeffrey Richer的CLR via C#。它有一個關於線程的精彩部分,以及在.Net代碼中使用它們的不同方法。