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

发布于 2024-10-29 04:35:02 字数 1171 浏览 1 评论 0原文

我的程序中有三个线程,我希望当线程 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");
            }
        }
    }

I have three threads in my program and I want that when thread one finishes it signals thread 2 to start and when thread 2 finishes it should signal thread 3 to start.

How can I achieve this, I know there are wait handles to do that in C#, but I don't know how to use them ?

Following is the code of my program:

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");
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

百变从容 2024-11-05 04:35:03

您似乎想要运行任务 1 - 3 以同步执行。因此,您不妨这样做:

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

如果您想将这些任务的执行卸载到另一个线程,您可以这样做:

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

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

如果您确实希望每个任务在单独的线程上运行,并等待要完成上一个任务,您可以使用 Thread.Join< /code>方法。

编辑

由于您确实想使用等待句柄来完成此操作,请查看 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();

It appears that you want to run Tasks 1 - 3 to execute synchronously. So, you might as well do:

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

If you want to offload the execution of these tasks to another thread, you can do:

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

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

If you really wanted each task to run on a separate thread, and wait for the previous task to finish, you can use the Thread.Join method.

EDIT:

Since you really want to use wait-handles to accomplish this, take a look at the ManualResetEvent class.

Notifies one or more waiting threads
that an event has occurred.

Call the WaitOne method on it to wait on the event, and the Set method to signal it.

Example (horribly contrived code):

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();
岛歌少女 2024-11-05 04:35:03

如果你想使用WaitHandles来实现这些,那么你可以执行以下操作:

声明以下两个字段:

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

然后在Task1的末尾,添加以下内容:

    handle1.Set();

在Task2的开头,添加:

    handle1.WaitOne();

then在末尾,添加

    handle2.Set();

然后最后在Task3 开头添加

    handle2.WaitOne();

If you want to use WaitHandles to acheive these then you could do the following:

declare the following two fields:

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

then at the end of Task1, add this:

    handle1.Set();

at the beginning of Task2, add:

    handle1.WaitOne();

then at the end, add

    handle2.Set();

then finally at the beginning of Task3 add

    handle2.WaitOne();
深海不蓝 2024-11-05 04:35:03

这感觉很人为,几乎就像家庭作业……

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

或者旧的 msdn 教程/示例对此非常合理: http ://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx

This feels very artificial, almost like homework...

... but basically you can use Join on a thread to wait for it.

Or the old msdn tutorial/example is very reasonable on this: http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx

郁金香雨 2024-11-05 04:35:03

您可以使用 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
}

You could use ManualResetEvents and WaitHandle.WaitAny. Basically when one thread is done you would notify the other thread by using a 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
}
别闹i 2024-11-05 04:35:03

我认为使用 thread.join() 会更简单任何其他解决方案

i think using thread.join() will be more simpler any other solution

遮云壑 2024-11-05 04:35:02

您需要将事件传递到线程函数中,以指示每个事件完成时发出的信号以及运行之前要等待的内容。看看下面的(未经测试的)代码就明白我的意思了:

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();
        }
    }

You need to pass events into the threaded functions that indicate what to signal when each one has finished and what to wait on before they run. Take a look at the (untested) code below to see what I mean:

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();
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文