2011-04-14 129 views
3

我可以通過進一步閱讀來解決這個問題,我想你應該參考線索而不是物件。它現在有效。 :)C# - 如何喚醒睡眠線程?

原帖:


我看着到大多數的類似的問題,我已經看到了很多包含顯示器,豆類等的答案,但是我不能使它工作。

我對C#很陌生,所以如果我使用線程錯誤,請原諒我。但我的問題如下:

我有4個線程,其中一個將三個不同表中的一個整數減少一個。然後根據是否有任何值達到零來執行動作的3個不同線程。

我想要做的是讓線程倒計時只喚醒三個其他人的正確線程,如果一些東西達到零。檢查這不是問題,問題是要喚醒線程。我現在有一個工作,他們都只是一次運行,但我想用它來使其效率。

這裏是我使用的代碼,爲了簡單起見,我只包含了一個代碼,它也是一樣的想法。這是我應該如何使用它?

這是我通過閱讀谷歌上的例子和結果得到的。

public class UpdateQueueSuggestion 

{

public void startGame() 
{  
    Thread Check = new Thread(new ThreadStart(checkUpdate)); 
    Check.Start(); 
} 

public void checkUpdate() 
{ 
    // (...) Some intialization of variables 

    // Create the thread used for when entries in the Queue table reaches 0. 
    Thread Build = new Thread(new ThreadStart(performBuildingUpdate)); 
    Build.Start(); 

    // Some sqlcommands. 

    while (true) 
    { 
     try 
     { 
      // Enter to synchronize, if not it yields 
      // Object synchronization method was called from an unsynchronized block of code. 
      Monitor.Enter(this); 
      connection.Open(); 

      // Execute commands. Get COUNT(*) for results reaching 0 in tables and save int in i. 

      if (i > 0) 
      { 
      // Pulse the thread called Build, in order to wake it again. 
       Monitor.Pulse(Build); 
      } 
     } 

     finally 
     { 
      // Exit monitor. 
      Monitor.Exit(this); 
      connection.Close(); 
     } 
     // This one is supposed to run each second, decrement and check for zeros. 
     // Works just fine if I just put everything in here without monitors, 
     // but as I said I want to split it up for efficiency. 
     Thread.Sleep(1000); 
    } 

} 

public void performBuildingUpdate() 
{ 
    // Some sqlcommands 

    while (true) 
    { 
     Monitor.Enter(this); 
     try 
     { 
      connection.Open(); 
      // Execute commands. 
     } 

     finally 
     { 
      connection.Close(); 
      Monitor.Wait(this); 
      Monitor.Exit(this); 
     } 
    } 

} 

}

任何幫助感激,謝謝。

如果有人想知道,這是針對我們在學校爲C#課程開發的瀏覽器遊戲項目。這應該是遊戲事件的大致時間。目前我們正在使用一個線程中的所有命令並每10秒運行一次。如果能夠每秒運行一次,那將是非常棒的。

+3

建議您閱讀這個優秀的資源:http://www.albahari.com/threading/ – 2011-04-14 03:22:38

+0

請不要使用前綴,而不是解決標誌標題答案(甚至在需要時添加) – 2011-04-14 06:24:16

回答

0

要做到這一點最直接的方法是擁有三個單獨的鎖定對象,每個工作線程將等待特定的鎖定,並且控制線程將根據遞減的值脈衝鎖定正確的鎖定。

public class Controller 
{ 
    private object _lock1; 
    private object _lock2; 
    private object _lock3; 

    private Thread _worker1; 
    private Thread _worker2; 
    private Thread _worker3; 


    public Controller() 
    { 
     _lock1 = new object(); 
     _lock2 = new object(); 
     _lock3 = new object(); 

     _worker1 = new Thread(ExecuteWorker, _lock1); 
     _worker2 = new Thread(ExecuteWorker, _lock2); 
     _worker3 = new Thread(ExecuteWorker, _lock3); 

     lock (_lock1) 
     { 
      _worker1.Start(); 
      Monitor.Wait(_lock1); 
     } 
     lock (_lock2) 
     { 
      _worker2.Start(); 
      Monitor.Wait(_lock2); 
     } 
     lock (_lock3) 
     { 
      _worker3.Start(); 
      Monitor.Wait(_lock3); 
     } 
    } 

    public void Execute() 
    { 
     // Perform database logic, assuming decremented values are stored. 
     int value1 = DecrementValueFromDB(); 
     int value2 = DecrementValueFromDB(); 
     int value3 = DecrementValueFromDB(); 

     if (value1 == 0) 
     { 
      lock (_lock1) 
      { 
       Monitor.Pulse(_lock1); 
      } 
     } 

     if (value2 == 0) 
     { 
      lock (_lock2) 
      { 
       Monitor.Pulse(_lock2); 
      } 
     } 

     /// ... repeat for third value 
     // 
    } 
} 

每個工人正在運行是這樣的:

static void ExecuteWorker(object lockObject) 
{ 
    lock (lockObject) 
    { 
     // Signal to thread creator that the thread is running. 
     Montior.Pulse(lockObject); 

     // Keep running while we have not been marked to shut down 
     while (!complete) 
     { 
      Monitor.Wait(lockObject); 
      // logic to execute when signaled (value == 0) 
     } 
    } 
}