如何等待线程完成后再继续执行?

13

我有一些用于在.NET CF 2.0上启动线程的代码:

ThreadStart tStart = new ThreadStart(MyMethod);
Thread t = new Thread(tStart);
t.Start();

如果我在循环内调用此函数,那么项目的顺序会完全混乱。如何在t.Start()之后引入等待,以便线程上的工作在代码继续之前完成? 使用BeginInvoke / EndInvoke是否比手动创建线程更好?

3个回答

16

你需要对线程进行多少排序?如果你只需要在循环中启动的所有工作完成后代码才继续运行,但是你不关心循环内部的工作完成顺序,那么调用Join就是答案。为了更详细地解释Kevin Kenny的回答,你应该在循环调用Join。这意味着你需要一个集合来保存你启动的线程的引用:

// Start all of the threads.
List<Thread> startedThreads = new List<Thread>();
foreach (...) {
  Thread thread = new Thread(new ThreadStart(MyMethod));
  thread.Start();
  startedThreads.Add(thread);
}

// Wait for all of the threads to finish.
foreach (Thread thread in startedThreads) {
  thread.Join();
}

相反,如果在循环内部调用Join,则结果基本上与不使用线程相同。循环体的每次迭代都会创建并启动一个线程,但随后立即加入它并等待其完成。
如果各个线程产生某些结果(例如,在日志中编写消息),则消息仍可能因线程之间缺乏协调而显示为无序的。通过使用监视器来协调线程,可以使线程按顺序输出它们的结果。

5

等待线程完成的另一种方式是使用 AutoResetEvent

private readonly AutoResetEvent mWaitForThread = new AutoResetEvent(false);

private void Blah()
{
    ThreadStart tStart = new ThreadStart(MyMethod);
    Thread t = new Thread(tStart);
    t.Start();

    //... (any other things)
    mWaitForThread.WaitOne();
}

private void MyMethod()
{
     //... (execute any other action)
     mWaitForThread.Set();
}

4
如果我理解正确,您正在启动一堆线程上的工作项,但担心线程完成顺序不正确,并且希望等待每个线程按照它们启动的顺序依次完成?
如果是这种情况,那么我不确定为什么您要为每个工作项创建一个线程。也许您可以进一步解释一下?
如果您确实需要等待线程完成,则可以执行以下操作:
t.Join();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接