首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等待线程完成

等待线程完成
EN

Stack Overflow用户
提问于 2012-06-23 00:08:33
回答 4查看 45.3K关注 0票数 5
代码语言:javascript
复制
    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 15; i++)
        {
            Thread nova = new Thread(Method);
            nova.Start();
        }
        listBox1.Items.Add("Some text");
    }

    private void Method()
    {
        for (int i = 0; i < 15; i++)
        {
            Console.WriteLine(i);
        }

    }

这段代码写道:一些文本,然后是数字111222333.....我希望它写成111122223333....然后在最后写一些文字。有没有可能用线程(父线程等待子线程)来实现?或者我必须使用其他东西?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-23 00:23:56

我建议使用TPL来完成这项工作。你不需要产生这么多的线程。默认情况下,TPL将使用线程池:

代码语言:javascript
复制
using System;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        private const int TaskCount = 15;

        static void Main(string[] args)
        {
            var tasks = new Task[TaskCount];
            for (var index = 0; index < TaskCount; index++)
            {
                tasks[index] = Task.Factory.StartNew(Method);
            }
            Task.WaitAll(tasks);

            Console.WriteLine("Some text");
        }

        private static void Method()
        {
            for (int i = 0; i < 15; i++)
            {
                Console.WriteLine(i);
            }
        }
    }
}
票数 10
EN

Stack Overflow用户

发布于 2012-06-23 00:10:29

您需要跟踪所有线程,并在每个线程上使用Thread.Join。它会一直等到指定的线程终止,然后继续执行。如下所示:

代码语言:javascript
复制
var threads = new List<Thread>();
for (int i = 0; i < 15; i++)
{
    Thread nova = new Thread(Method);
    nova.Start();
    threads.Add(nova);
}
foreach (var thread in threads)
    thread.Join();
listBox1.Items.Add("Some text");
票数 15
EN

Stack Overflow用户

发布于 2012-06-23 00:13:17

你可以有两个线程,第二个线程等待第一个线程发出触发信号。

代码语言:javascript
复制
private void Foo()
{
  var signals = new List<ManualResetEvent>();

  for (int i = 0; i < 15; i++)
  {
    var signal = new ManualResetEvent(false);
    signals.Add(signal);
    var thread = new Thread(() => { Method(); signal.Set(); });
    thread.Start();
  }

  var completionTask = new Thread(() =>
  {
    WaitHandle.WaitAll(signals.ToArray());
    CompletionWork();
  });
  completionTask.Start();

}

private void Method()
{
}

private void CompletionWork()
{
}

现在.Net 4.0 (及更高版本)中更好的解决方案是使用任务,并使用ContinueWith调用方法

代码语言:javascript
复制
private void Foo()
{
  var childThreads = new List<Task>();
  for (int i = 0; i < 15; i++)
  {
    var task = new Task(Method);
    task.Start();
    childThreads.Add(task);
  }

  var completionTask = new Task(() => 
  { 
    Task.WaitAll(childThreads.ToArray());
  }).ContinueWith(t => CompletionWork());

}

private void Method()
{
}

private void CompletionWork()
{
}

join应答也可以,但需要包含线程阻塞。如果你不想让GUI阻塞,在第一个线程周围产生一个额外的线程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11160021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档