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

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

问题描述

我从来没有真正用在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, my question is how to have a thread wait for another one to finish. What is the best way to do this?

推荐答案

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

I can see 5 options available:

与米奇的回答。但是,这将阻止你的UI线程,但是你建你超时。

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

的ManualResetEvent 的WaitHandle 作为jrista建议。

ManualResetEvent is a WaitHandle as jrista suggested.

需要注意的一点是,如果你想等待多线程, WaitHandle.WaitAll的()将默认情况下不工作,因为它需要一个MTA线程。你可以解决这个问题通过 MTAThread 标记你的的Main()法 - 然而,这阻止你的消息泵和ISN从我读过建议吨。

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.

请参阅这个页面乔恩斯基特有关事件和多线程,它可能是一个事件可以成为如果事件名称(这一点,EventArgs.Empty)之间unsuscribed - 这是之前发生在我身上。

See this page by Jon Skeet about events and multi-threading, it's possible that an event can become unsuscribed 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(HandleThreadDone);

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

        _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天全站免登陆