2009-07-30 62 views
6

我需要通知所謂的工作線程停止下一個可用oppertunity的工作。目前我使用這樣的事情:通知線程停止的選項

public void Run() 
    { 
     while (!StopRequested) 
      DoWork(); 
    } 

我所關注的是StopRequested被設置爲True在不同的線程。這安全嗎?我知道我不能鎖定布爾值。也許有一種不同的方式告訴線程需要停止。例如,我很樂意檢查Thread.CurrentThread.ThreadState == ThreadState.StopRequested,但我不清楚如何設置線程狀態。

+0

爲什麼你不能鎖定一個布爾值?無論如何,爲任何鎖定創建單獨的「對象」通常被認爲是很好的做法。 – 2009-07-30 18:36:25

+0

我不能鎖定布爾,因爲它的值類型 - 我可以創建一個所謂的同步對象,除了在獲取/設置布爾標誌時鎖定它 - 但在我看來,鎖定在布爾應該是安全的,至少裏德科普塞同意 – 2009-07-30 18:58:44

+0

是的,圍繞布爾鎖定應該是安全的。合作取消。如果Backgroundworker適合您正在執行的任務,則支持類似的概念。 – 2009-07-31 03:20:41

回答

3

這是比嘗試設置ThreadState更好的方法。如果您查看ThreadState的文檔,它特別指出StopRequested僅供內部使用。

從另一個線程設置布爾值是安全操作。你不應該在這種情況下鎖定。

2

使用Event對象可能會更好。特別是如果你的線程阻塞。 (然後你仍然可以等待阻塞呼叫中的事件)

3

您可能想要看看如何使用BackgroundWorker爲您完成工作,在您的邏輯過程中使用RunWorkerAsync()並處理worker.CancellationPending == true的情況。

BackgroundWorker worker = new BackgroundWorker(); 
worker.WorkerSupportsCancellation = true; 
worker.DoWork += MyWorkFunction; 
worker.RunWorkerCompleted += MyWorkDoneSuccessfullyFunction; 
worker.RunWorkerAsync(); 

另一種解決方案是使用易揮發的布爾表示需要停下來,這可以在課堂上的任何位置設置。

private volatile bool cancelWork = false; 

public void CancelWork() 
{ 
    cancelWork = true; 
} 
2

您可以使用Thread.Abort()並在finally塊的DoWork()方法中包裝所有必要的清理。

0

如果使用BackgroundWorker,你會叫的BackgroundWorker的CancelAsync功能設置CancellationPending屬性爲true,這是你能看到在你的循環是什麼:

public void Run(object sender, DoWorkEventArgs e) 
{  
    BackgroundWorker worker = sender as BackgroundWorker; 
    if(worker != null) 
    { 
     while (!worker.CancellationPending) 
     { 
     DoWork(); 
     } 
    } 
} 

以上將是DoWork事件代碼在您運行RunWorkerAsync函數時調用。

1

的關心我是 StopRequested被設置爲true 不同的線程。這安全嗎?

你應該確保在StopRequested場有volatile關鍵字。爲什麼請參閱this other answer