如何在C#线程中使用等待句柄?

如何在C#线程中使用等待句柄?,c#,multithreading,C#,Multithreading,我的程序中有三个线程,我希望当线程1完成时,它会向线程2发出启动信号,当线程2完成时,它会向线程3发出启动信号 我知道在C#中有等待句柄可以实现这一点,但我不知道如何使用它们 以下是我的程序代码: class Program { static void Main(string[] args) { Thread t1 = new Thread(Task1); Thread t2 = new Thread(Tas

我的程序中有三个线程,我希望当线程1完成时,它会向线程2发出启动信号,当线程2完成时,它会向线程3发出启动信号

我知道在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");
            }
        }
    }
类程序
{
静态void Main(字符串[]参数)
{
线程t1=新线程(任务1);
线程t2=新线程(任务2);
线程t3=新线程(任务3);
t1.Start();
t2.Start();
t3.Start();
Console.Read();
}
公共静态void Task1()
{
Console.WriteLine(“我被分配任务1:”);
对于(int i=0;i<50;i++)
{
控制台写入线(“任务1”);
}
}
公共静态void Task2()
{
Console.WriteLine(“我被分配任务2:”);
对于(int i=0;i<50;i++)
{
Console.WriteLine(“任务2”);
}
}
公共静态无效任务3()
{
Console.WriteLine(“我被分配任务3:”);
对于(int i=0;i<50;i++)
{
Console.WriteLine(“任务3”);
}
}
}

您似乎希望运行任务1-3以同步执行。因此,您不妨:

Task1();
Task2();
Task3();
如果要将这些任务的执行转移到另一个线程,可以执行以下操作:

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

static void Main()
{
   new Thread(RunTasks).Start();
}
如果确实希望每个任务在单独的线程上运行,并等待上一个任务完成,则可以使用该方法

编辑

由于您确实希望使用等待句柄来完成此任务,请查看该类

通知一个或多个等待线程 事件已经发生

对其调用
WaitOne
方法以等待事件,并调用
Set
方法以向其发送信号

示例(可怕的人为代码):


您需要将事件传递到线程函数中,这些线程函数指示在每个线程完成时发送什么信号,以及在运行之前等待什么。看看下面的(未测试的)代码,了解我的意思:

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();
        }
    }
类程序
{
静态void Main(字符串[]参数)
{
线程t1=新线程(任务1);
ManualResetEvent e1=新的ManualResetEvent(错误);
线程t2=新线程(任务2);
ManualResetEvent e2=新的ManualResetEvent(错误);
线程t3=新线程(任务3);
ManualResetEvent e3=新的ManualResetEvent(错误);
t1.启动(()=>Task1(e1));
t2.开始(()=>Task2(e1,e2));
t3.开始(()=>Task3(e2,e3);
Console.Read();
t1.Join();
t2.连接();
t3.Join();
}
公共静态void Task1(EventWaitHandle句柄)
{
Console.WriteLine(“我被分配任务1:”);
对于(int i=0;i<50;i++)
{
控制台写入线(“任务1”);
}
handle.Set();
}
公共静态void Task2(eventwaithandlewaitfor、EventWaitHandle句柄)
{
waitFor.WaitOne();
Console.WriteLine(“我被分配任务2:”);
对于(int i=0;i<50;i++)
{
Console.WriteLine(“任务2”);
}
handle.Set();
}
公共静态void Task3(eventwaithandlewaitfor、EventWaitHandle句柄)
{
waitFor.WaitOne();
Console.WriteLine(“我被分配任务3:”);
对于(int i=0;i<50;i++)
{
Console.WriteLine(“任务3”);
}
handle.Set();
}
}

这感觉很做作,几乎像是家庭作业

…但基本上您可以在线程上使用
Join
来等待它


或者旧的msdn教程/示例在这方面非常合理:

您可以使用ManualResetEvents和WaitHandle.WaitAny。基本上,当一个线程完成时,您将使用ManualResetEvent(ManualResetEvent.Set())通知另一个线程


如果要使用WaitHandles实现这些,则可以执行以下操作:

声明以下两个字段:

static ManualResetEvent handle1 = new ManualResetEvent(false);
static ManualResetEvent handle2 = new ManualResetEvent(false);
然后在Task1的末尾添加以下内容:

    handle1.Set();
在任务2的开头,添加:

    handle1.WaitOne();
然后在最后,添加

    handle2.Set();
最后,在Task3的开头添加

    handle2.WaitOne();

我认为使用任何其他解决方案都会更简单

您可以将
t2
作为参数传递到
t1.Start
中,然后在
Task1
的末尾调用
t2.Start()
使用您得到的参数。要使其起作用,请改用。我的问题的目的是了解等待句柄是如何工作的?因此,请给我一个例子……您的等待句柄名称当前已关闭。@BrokenGlass:没错。这样Task2和Task3一开始不会阻塞。Task1将设置Task2正在等待的句柄。然后,w当Task2完成后,它将设置Task3正在等待的句柄。我不明白。它们在main()中声明,每个TaskXXX方法都传递了句柄。您认为哪里缺少声明?
    handle2.Set();
    handle2.WaitOne();