C#等待多个线程完成

And*_*ndy 36 c# multithreading

我有一个Windows窗体应用程序,我正在检查所有串行端口,以查看是否已连接特定设备.

这就是我脱掉每个线程的方式.下面的代码已经从主要的gui线程中分离出来.

foreach (cpsComms.cpsSerial ser in availPorts)
{
    Thread t = new Thread(new ParameterizedThreadStart(lookForValidDev));
    t.Start((object)ser);//start thread and pass it the port
}
Run Code Online (Sandbox Code Playgroud)

我希望下一行代码等到所有线程都完成.我尝试过t.join在那里使用a ,但这只是线性处理它们.

Yur*_*ich 42

List<Thread> threads = new List<Thread>();
foreach (cpsComms.cpsSerial ser in availPorts)
{
    Thread t = new Thread(new ParameterizedThreadStart(lookForValidDev));
    t.Start((object)ser);//start thread and pass it the port
    threads.Add(t);
}
foreach(var thread in threads)
{
    thread.Join();
}
Run Code Online (Sandbox Code Playgroud)

编辑

我回头看这个,我更喜欢以下内容

availPorts.Select(ser =>
      {
          Thread thread = new Thread(lookForValidDev);
          thread.Start(ser);
          return thread;
      }).ToList().ForEach(t => t.Join());
Run Code Online (Sandbox Code Playgroud)


Isl*_*ene 16

使用AutoResetEvent和ManualResetEvent类:

private ManualResetEvent manual = new ManualResetEvent(false);
void Main(string[] args)
{
    AutoResetEvent[] autos = new AutoResetEvent[availPorts.Count];

    manual.Set();

    for (int i = 0; i < availPorts.Count - 1; i++)
        {

        AutoResetEvent Auto = new AutoResetEvent(false);
        autos[i] = Auto;

        Thread t = new Thread(() => lookForValidDev(Auto, (object)availPorts[i]));
        t.Start();//start thread and pass it the port  

    }
    WaitHandle.WaitAll(autos);
    manual.Reset();

}


void lookForValidDev(AutoResetEvent auto, object obj)
{
    try
    {
         manual.WaitOne();
         // do something with obj 
    }
    catch (Exception)
    {

    }
    finally
    {
        auto.Set();
    }


} 
Run Code Online (Sandbox Code Playgroud)

  • 这里的ManualResetEvent有什么意义? (4认同)
  • auto.Set()应该在finally块中 (2认同)

Iam*_*mIC 7

最简单和最安全的方法是使用CountdownEvent.见阿尔巴哈里.