如何等待线程完成.NET? [英] How can I wait for a thread to finish with .NET?

查看:81
本文介绍了如何等待线程完成.NET?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前从未真正在C#中使用过线程,在C#中,我需要有两个线程以及主UI线程。基本上,我有以下内容。

I've never really used threading before in C# where I need to have two threads, as well as the main UI thread. Basically, I have the following.

public void StartTheActions()
{
  // Starting thread 1....
  Thread t1 = new Thread(new ThreadStart(action1));
  t1.Start();

  // Now, I want for the main thread (which is calling `StartTheActions` method)
  // to wait for `t1` to finish. I've created an event in `action1` for this.
  // The I wish `t2` to start...

  Thread t2 = new Thread(new ThreadStart(action2));
  t2.Start();
}

因此,从本质上讲,我如何让一个线程等待另一个线程完成?最好的方法是什么?

So, essentially, how can I have a thread wait for another one to finish? What is the best way to do this?

推荐答案

我可以看到五个可用的选项:

I can see five options available:

与Mit​​ch的答案一样。但这会阻塞您的UI线程,但是会为您内置一个超时。

As with Mitch's answer. But this will block your UI thread, however you get a Timeout built in for you.

ManualResetEvent WaitHandle 建议使用

ManualResetEvent is a WaitHandle as jrista suggested.

要注意的一件事是,是否要等待多个线程: WaitHandle.WaitAll()默认情况下将不起作用,因为它需要一个 MTA 线程。您可以通过使用 MTAThread 标记您的 Main()方法来解决此问题-但是,这会阻止您的消息泵,并且不会

One thing to note is if you want to wait for multiple threads: WaitHandle.WaitAll() won't work by default, as it needs an MTA thread. You can get around this by marking your Main() method with MTAThread - however this blocks your message pump and isn't recommended from what I've read.

请参见此页的作者Jon Skeet 关于事件和多线程。 if EventName(this,EventArgs.Empty)之间的事件可能会取消订阅-发生了

See this page by Jon Skeet about events and multi-threading. It's possible that an event can become unsubcribed between the if and the EventName(this,EventArgs.Empty) - it's happened to me before.

(希望这些编译,我没有尝试过)

public class Form1 : Form
{
    int _count;

    void ButtonClick(object sender, EventArgs e)
    {
        ThreadWorker worker = new ThreadWorker();
        worker.ThreadDone += HandleThreadDone;

        Thread thread1 = new Thread(worker.Run);
        thread1.Start();

        _count = 1;
    }

    void HandleThreadDone(object sender, EventArgs e)
    {
        // You should get the idea this is just an example
        if (_count == 1)
        {
            ThreadWorker worker = new ThreadWorker();
            worker.ThreadDone += HandleThreadDone;

            Thread thread2 = new Thread(worker.Run);
            thread2.Start();

            _count++;
        }
    }

    class ThreadWorker
    {
        public event EventHandler ThreadDone;

        public void Run()
        {
            // Do a task

            if (ThreadDone != null)
                ThreadDone(this, EventArgs.Empty);
        }
    }
}




4。使用委托


public class Form1 : Form
{
    int _count;

    void ButtonClick(object sender, EventArgs e)
    {
        ThreadWorker worker = new ThreadWorker();

        Thread thread1 = new Thread(worker.Run);
        thread1.Start(HandleThreadDone);

        _count = 1;
    }

    void HandleThreadDone()
    {
        // As before - just a simple example
        if (_count == 1)
        {
            ThreadWorker worker = new ThreadWorker();

            Thread thread2 = new Thread(worker.Run);
            thread2.Start(HandleThreadDone);

            _count++;
        }
    }

    class ThreadWorker
    {
        // Switch to your favourite Action<T> or Func<T>
        public void Run(object state)
        {
            // Do a task

            Action completeAction = (Action)state;
            completeAction.Invoke();
        }
    }
}

如果确实使用_count方法,则可能是一个想法(为了安全起见)使用

If you do use the _count method, it might be an idea (to be safe) to increment it using

Interlocked.Increment(ref _count)

我想知道使用委托和事件进行线程通知之间的区别,我所知道的唯一区别是事件被同步调用。

I'd be interested to know the difference between using delegates and events for thread notification, the only difference I know are events are called synchronously.

此问题的答案使用此方法对选项进行了非常清晰的描述。

The answer to this question has a very clear description of your options with this method.

事件/委托的处理方式将意味着您的事件处理程序方法位于线程1 /线程2 上而不是主UI线程上,因此您需要向右切换在HandleThreadDone方法的顶部:

The event/delegate way of doing things will mean your event handler method is on thread1/thread2 not the main UI thread, so you will need to switch back right at the top of the HandleThreadDone methods:

// Delegate example
if (InvokeRequired)
{
    Invoke(new Action(HandleThreadDone));
    return;
}

这篇关于如何等待线程完成.NET?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆