代码之家  ›  专栏  ›  技术社区  ›  sbi

如何在C中使这个循环的体并行运行#

  •  2
  • sbi  · 技术社区  · 16 年前

    我有一个这样的循环

    ICollection<Data> GetData()
    {
      ICollection<Data> result = new List<Data>()
      foreach (var item in aCollection)
        item.AddData(result);
      return result;
    }
    

    我现在需要并行执行,而不是迭代执行。我第一次尝试就是做这样的事

    ICollection<Data> GetData()
    {
      ICollection<Data> result = new SynchronizedCollection<Data>()
      foreach (var item in aCollection)
        new Thread(delegate() { item.AddData(result); }).Start();
      return result;
    }
    

    编辑: AddData

    5 回复  |  直到 16 年前
        1
  •  2
  •   Oliver Hanappi    16 年前

    您可以使用并行扩展,它将集成在C#4.0中,并可作为单独的库用于C#3.5,您可以在此处下载: Microsoft Parallel Extensions to .NET Framework 3.5 .

            IEnumerable<object> providers = null;
    
            var waitHandles = new List<WaitHandle>();
            foreach (var provider in providers)
            {
                var resetEvent = new ManualResetEvent(false);
                waitHandles.Add(resetEvent);
    
                ThreadPool.QueueUserWorkItem(s =>
                 {
                     // do whatever you want.
                     ((EventWaitHandle)s).Set();
                 }, resetEvent);
            }
    
            WaitHandle.WaitAll(waitHandles.ToArray());
    
        2
  •  2
  •   Brian Rasmussen    16 年前

    如果你真的想把它交给其他线程,你应该使用ThreadPool。至于等待线程完成,您可以使用等待句柄在线程之间发送信号。

        3
  •  1
  •   Razzie    16 年前

    Parallel.ForEach<Data>(aCollection, delegate(Data d)
    {
      d.AddData(result);
    });
    
        4
  •  0
  •   flq    16 年前

    最简单的方法可能是等待4.0中的并行框架。

    现在,对于初学者来说,你需要小心那里的线程创建。如果你有数百甚至数千个项目,这些代码可能会扼杀你的应用程序,或者至少是你的性能。

    我会尝试设计 添加数据 IAsyncResult 有一个WaitHandle。您可以等待这些句柄,直到所有asyncresults都声明操作已完成。然后可以继续。异步执行此操作应确保使用线程池中的线程。这样,您可以获得相当好的性能,如果您的列表变得非常大,您可以达到工作线程的自然饱和。

        5
  •  -1
  •   Blindy    16 年前

    存储对您创建的线程对象的引用,并对每个对象调用join:

    ICollection<Data> GetData()
    {
      ICollection<Data> result = new SynchronizedCollection<Data>()
      List<Thread> threads=new List<Thread>();
    
      foreach (var item in aCollection)
      {
        Thread thread=new Thread(delegate() { item.AddData(result); });
        thread.Start();
        threads.Add(thread);
      }
    
      foreach(Thread thread in threads)
        thread.Join();
    
      return result;
    }