【问题标题】:Please help. Creating threads and wait till finish [duplicate]请帮忙。创建线程并等待完成[重复]
【发布时间】:2012-07-12 00:15:47
【问题描述】:

可能重复:
C# Spawn Multiple Threads for work then wait until all finished

我有两个方法调用,我想使用两个线程进行调用。然后我希望他们等到方法执行完成后再继续。我的示例解决方案如下所示。

    public static void Main()
    {   
        Console.WriteLine("Main thread starting.");
        String[] strThreads = new String[] { "one", "two" };

        String ctemp = string.Empty;
        foreach (String c in strThreads)
        {
            ctemp = c;
            Thread thread = new Thread(delegate() { MethodCall(ctemp); });
            thread.Start();
            thread.Join();
        }

        Console.WriteLine("Main thread ending.");
        Console.Read();
    }


    public static void MethodCalls(string number)
    {
        Console.WriteLine("Method call " + number);
    }

这样可以吗?还是有其他更好的方法来做同样的事情?

【问题讨论】:

  • 扔掉你的'thread.Join();'循环外的语句。

标签: c# .net multithreading


【解决方案1】:

我会考虑通过ThreadPool.QueueUserWorkItem 运行您的方法,然后使用WaitHandle.WaitAll 等待它们全部完成。

【讨论】:

  • +1,启动一个专用线程并等待它完成通常不是最好的主意。除了启动成本之外,还很难控制并发执行任务的数量。 .NET 4 中的 Task API 更适合这一点。
  • 当委托可以以类型安全的方式做同样的事情时,你为什么还要考虑 QeuUserWorkItem。 WaitHandle.WaitAll 不允许您处理异常。
【解决方案2】:

这一系列语句...:

        Thread thread = new Thread(delegate() { MethodCall(ctemp); });
        thread.Start();
        thread.Join();

相当于直接调用该方法——因为您正在等待新线程在启动后立即完成,所以线程没有任何好处!您需要首先在一个循环中启动所有线程(将它们放在一个数组列表或一些类似的容器中),然后将它们加入一个单独的循环中,以获得并发执行方法。

【讨论】:

  • 再一次,当你有一个非常好的线程池时,你为什么要为此滚动一个线程。
【解决方案3】:

你正在做的就是创建一个线程,然后一个接一个地等待完成。在任何时候,您最多运行两个线程:主线程和启动线程。

你想要的是启动所有线程,然后等待所有线程完成:

public static void Main()
{   
    Console.WriteLine("Main thread starting.");
    String[] strThreads = new String[] { "one", "two" };

    int threadCount = strThreads.Length;
    AutoResetEvent eventdone = new AutoResetEvent(false);

    String ctemp = string.Empty;
    foreach (String c in strThreads)
    {
        ctemp = c;
        Thread thread = new Thread(delegate() { 
            try
            {
               MethodCall(ctemp); 
            }
            finally 
            {
               if (0 == Interlocked.Decrement(ref threadCount) 
               {
                  eventDone.Set();
               }
            }
        });
        thread.Start();
    }

    eventDone.WaitOne();

    Console.WriteLine("Main thread ending.");
    Console.Read();
}


public static void MethodCalls(string number)
{
    Console.WriteLine("Method call " + number);
}

【讨论】:

  • 可能是个仇恨者,我 +1。
  • 顺便说一句,我完全同意 Jay 关于使用 ThreadPool 的观点。但我不同意使用 WaitAll,因为 64 句柄限制,如果没有别的。
  • 这太复杂了。使用线程池。
【解决方案4】:

如果你打算让你的两个线程一个接一个地执行,那么是的,上面的代码就足够了(虽然我的 C# 语法知识有点模糊,所以我不能说如果上面编译好不好),但是如果你想要有序的同步执行,为什么要使用线程呢?

如果您希望两个方法调用并行执行,则需要将 thread.Join(); 从 for 循环中取出(您需要挂在线程对象上,可能在数组中.)

【讨论】:

    【解决方案5】:

    看看BackgroundWorker Component;我相信它适用于 Windows 窗体、WPF 和 Silverlight,基本上涉及 UI 的地方

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 2021-10-29
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多