2011-04-04 123 views
3

我在我的程序中有三個線程,我希望當線程完成時它表示線程2啓動,當線程2完成時它應該指示線程3啓動。如何在C#線程中使用等待句柄?

我該怎麼做到這一點,我知道在C#中有這樣的等待句柄,但我不知道如何使用它們?

以下是我的程序的代碼:

class Program 
    { 
     static void Main(string[] args) 
     { 
      Thread t1 = new Thread(Task1); 
      Thread t2 = new Thread(Task2); 
      Thread t3 = new Thread(Task3); 

      t1.Start(); 
      t2.Start(); 
      t3.Start(); 

      Console.Read(); 
     } 

     public static void Task1() 
     { 
      Console.WriteLine("I am assigned task 1:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task1"); 
      } 
     } 
     public static void Task2() 
     { 
      Console.WriteLine("I am assigned task 2:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task2"); 
      } 
     } 
     public static void Task3() 
     { 
      Console.WriteLine("I am assigned task 3:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task3"); 
      } 
     } 
    } 
+0

你可以在't1.Start'中傳遞't2'作爲參數,然後在'Task1'結尾使用你得到的參數調用't2.Start()'。爲此,請改用[ParameterizedThreadStart](http://msdn.microsoft.com/zh-cn/library/system.threading.parameterizedthreadstart.aspx)。 – 2011-04-04 13:14:47

回答

6

你需要傳遞事件到線索的功能,標明每一個已經完成了什麼信號和如何伺候他們跑了。看看下面的(未經測試)代碼,明白我的意思:

class Program 
    { 
     static void Main(string[] args) 
     { 
      Thread t1 = new Thread(Task1); 
      ManualResetEvent e1=new ManualResetEvent(false); 

      Thread t2 = new Thread(Task2); 
      ManualResetEvent e2=new ManualResetEvent(false); 

      Thread t3 = new Thread(Task3); 
      ManualResetEvent e3=new ManualResetEvent(false); 

      t1.Start(()=>Task1(e1)); 
      t2.Start(()=>Task2(e1,e2)); 
      t3.Start(()=>Task3(e2,e3); 

      Console.Read(); 

      t1.Join(); 
      t2.Join(); 
      t3.Join(); 
     } 

     public static void Task1(EventWaitHandle handle) 
     { 
      Console.WriteLine("I am assigned task 1:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task1"); 
      } 
      handle.Set(); 

     } 
     public static void Task2(EventWaitHandle waitFor, EventWaitHandle handle) 
     { 
      waitFor.WaitOne(); 

      Console.WriteLine("I am assigned task 2:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task2"); 
      } 

      handle.Set(); 
     } 
     public static void Task3(EventWaitHandle waitFor, EventWaitHandle handle) 
     { 
      waitFor.WaitOne(); 

      Console.WriteLine("I am assigned task 3:"); 
      for (int i = 0; i < 50; i++) 
      { 
       Console.WriteLine("Task3"); 
      } 

      handle.Set(); 
     } 
    } 
+0

您的等待手柄名稱目前已關閉。 – BrokenGlass 2011-04-04 13:21:40

+0

@BrokenGlass:是的。這樣Task2和Task3不會最初阻止。 Task1將設置Task2正在等待的句柄。然後,當Task2完成時,它將設置Task3正在等待的句柄。 – Sean 2011-04-04 13:24:34

+0

我的不好,我沒有正確地讀你的代碼,一切都很好 – BrokenGlass 2011-04-04 13:27:19

4

看來,要運行任務1 - 3執行同步。所以,你不妨做:

Task1(); 
Task2(); 
Task3(); 

如果你想卸載這些任務到另一個線程的執行,你可以這樣做:

static void RunTasks() 
{ 
    Task1(); 
    Task2(); 
    Task3(); 
} 

static void Main() 
{ 
    new Thread(RunTasks).Start(); 
} 

如果你真的想每個任務在運行單獨線程,並等待上一個任務完成,則可以使用Thread.Join方法。

編輯

既然你真的想使用等待句柄來做到這一點,看看在ManualResetEvent類。

通知一個或多個等待線程 發生了事件。

調用WaitOne方法就可以了,以等待該事件,並Set方法,以表示它。

例(可怕的做作代碼):

var afterT1Event = new ManualResetEvent(false); 
var afterT2Event = new ManualResetEvent(false); 

Thread t1 = new Thread(() => { Task1(); afterT1Event.Set(); }); 
Thread t2 = new Thread(() => { afterT1Event.WaitOne(); Task2(); afterT2Event.Set(); }); 
Thread t3 = new Thread(() => { afterT2Event.WaitOne(); Task3(); }); 

t1.Start(); 
t2.Start(); 
t3.Start(); 
+0

我的問題的目的是瞭解等待處理如何工作?所以,請舉例說明... – 2011-04-04 13:14:53

0

你可以使用ManualResetEvents和WaitHandle.WaitAny。基本上,當一個線程完成後,您將通過使用ManualResetEvent(ManualResetEvent.Set())通知另一個線程。

ManualResetEvent threadFinished = new ManualResetEvent(false); 

//You would set this in the thread that has finished 
threadFinished.Set() 

//You would use this in the thread that you want to wait for this event to be signalled 
int nWait = WaitHandle.WaitAny(new ManualResetEvent[] { threadFinished }, 10, true); 

//if yes stop thread 
if (nWait == 0) 
{ 
    //Thread is finished 
} 
2

如果你想使用WaitHandles到acheive這些,那麼你可以做到以下幾點:

聲明以下兩個領域:

static ManualResetEvent handle1 = new ManualResetEvent(false); 
static ManualResetEvent handle2 = new ManualResetEvent(false); 

然後在任務1月底,補充一點:

handle1.Set(); 

在任務2的開始,添加:

handle1.WaitOne(); 

然後在末尾添加

handle2.Set(); 

然後終於在任務3的開頭添加

handle2.WaitOne();