2013-04-23 61 views
0

Stop方法不能在另一個線程中修改字段isRunning,爲什麼?保持領域最新在多個線程修改和訪問在C#中?

這是MSDN的示例,但該字段僅由一個線程修改。

http://msdn.microsoft.com/en-us/library/x13ttww7(v=vs.110).aspx

以下是我的代碼。

public class Worker 
{ 
    private volatile bool isRunning; 

    public void Run() 
    { 
     ThreadPool.QueueUserWorkItem(DoSomething); 
    } 

    public void Stop() 
    { 
     this.isRunning = false; 
    } 

    private void DoSomething(object state) 
    { 
     this.isRunning = true; 
     while (this.isRunning) 
     { 
      Console.WriteLine("working..."); 
      Thread.Sleep(1000); 
     } 

     Console.WriteLine("stopped."); 
    } 

} 
+0

你在代碼中遇到了什麼異常? – 2013-04-23 07:10:55

+0

我想修改多個線程中的字段並將值保持最新。 – 2013-04-23 07:31:49

+0

但我測試了你的代碼,它確實是你想要的。也許你可以添加一些內聯評論來指出哪些功能無法按預期工作。 – 2013-04-23 07:32:47

回答

0

它確實有效。如果你運行這段代碼,你會看到,它工作得很好:

Worker worker = new Worker(); 
worker.Run(); 
Thread.Sleep(1000); 
worker.Stop(); 

的問題是,當您計劃執行的線程,它需要一些時間來執行。在我的示例中跳過Thread.Sleep(1000)的情況下,您立即將isRunning字段設置爲false,然後在線程執行時將其設置爲true。這就是爲什麼它永遠不會結束。

+0

謝謝!你指出錯誤在哪裏。 – 2013-04-23 07:43:36

+0

你的建議可行,但我不能同意。應該不允許使用該工作者的「客戶」知道該類內部的任何內容。所以使用Worker的程序員不應該知道「isRunning」的設置位置。這就是說,開發人員應該能夠立即調用Run和Stop,而不用暫停,因爲這應該很簡單。延遲只是防止工人級內部「隱藏」賽車狀況的一種技巧。 – 2013-04-23 08:01:12

+0

我從來沒有說過這是一個很好的解決方案。我只是指出了停止呼叫不起作用的原因。 – 2013-04-23 08:15:07

0

您應該將this.isRunning更改爲僅isRunning它指的是字段在另一個線程中運行時內存中的當前線程。

+0

不正確。 「this」參照一個對象的實例。這個實例可以被多個線程共享。結果,this.isRunning可以被多個線程共享(和修改)。其次,在這種情況下,添加或刪除「this」不會改變任何內容,因爲代碼仍然會反駁實例中的同一個字段。 – 2013-04-23 07:16:25

0

移動你的線isRunning = true的功能Run(),就像這樣:

公共類工人 { 私人揮發性布爾isRunning;

public void Run() 
{ 
    this.isRunning = true; 
    ThreadPool.QueueUserWorkItem(DoSomething); 
} 

public void Stop() 
{ 
    this.isRunning = false; 
} 

private void DoSomething(object state) 
{ 
    while (this.isRunning) 
    { 
     Console.WriteLine("working..."); 
     Thread.Sleep(1000); 
    } 

    Console.WriteLine("stopped."); 
} 

}

這一變化將確保isRunning是真實的,當函數DoSomething被調用。如果在RunDoSomething之間調用Stop,則該線程實際上會立即停止。

+0

我想在多個線程中修改&訪問字段,而不是在一個線程中修改它。 – 2013-04-23 07:27:41

+0

比我不明白你的問題。在你想調用「運行」的線程數量上,你想要調用多少個線程「停止」以及你運行多少個線程「DoSomething」?我問這個,因爲一個線程不會修改你的字段「isRunning」,只有你的方法。一個線程會調用你的方法。 – 2013-04-23 08:03:43