如何在C#线程中使用等待句柄?
我的程序中有三个线程,我希望当线程1完成时,它会向线程2发出启动信号,当线程2完成时,它会向线程3发出启动信号 我知道在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
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();