2011-04-04 67 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();