2017-07-27 55 views
2

我继承了一个具有很长项目列表的应用程序。使用线程加速进程

这花了几个小时循环,所以我想我可以通过运行线程来优化它。

例如:

 foreach (var d in data) 
     { 
      try 
      { 
       // do alot of logic, takes time 
      } 
      catch (Exception e) 
      { 
       // catch error 

      } 

     } 

我以为我可以通过优化它:

 foreach (var d in data) 
     { 
      try 
      { 
       ExecutionMethodThread(d); 
      } 
      catch (Exception e) 
      { 

      } 

     } 

    private void ExecutionMethodThread(data d) 
    { 
     Thread thread = new Thread(() => MethodThread(d)); 
     thread.Start(); 
     thread.Join(); 

    } 

虽然当我设置在foreach循环断点我还注意到,等待每个项目完成然后再进行下一步。 这显然不是我想要的,因为我希望这个列表能够通过循环运行 ,并且我将拥有多个项目,并拥有自己的线程simultaniosly。

我该如何做到这一点?

澄清:

循环开始

项目一启动一个线程和executs逻辑

项目不二的项目一个等待,都有自己的线程和executs 逻辑等

+5

'Parallel.ForEach'。小心你的逻辑必须是线程安全的。 –

+1

它不是多线程的,因为对于你处理的数据中的每一项,你都要等待它完成计算'加入',所以你永远不会同时计算多个项目 – litelite

+0

@litelite有没有办法绕过? –

回答

5

你需要两个循环。在第一个循环中,您将创建所有线程并启动它们。然后在第二个循环中,您将等待所有线程完成。

var threads = new List<Thread>(); 
foreach (var d in data) 
{ 
    Thread thread = new Thread(() => new MethodThread(d)); 
    thread.Start(); 
    threads.Add(thread); 
} 

foreach (var thread in threads) 
{ 
    try 
    { 
     thread.Join(); 
    } 
    catch (Exception e) 
    { 
     // ... 
    } 
} 

但是,这种方法仍然有一些缺点。如果您有一万个数据项要处理会发生什么?即使并非所有线程可以同时运行,您都将为每个数据项创建一个线程,这意味着您将不必要地使用资源。有一个简单的方法来达到同样的事情:

Parallel.ForEach(data, (datum) => 
{ 
    try 
    { 
     // Do your logic 
    } 
    catch (Exception e) 
    { 
     // ... 
    } 
}); 

C#会自动使用线程的合理数量,以满足您的处理器上可用内核的数量。

警告这假定您的逻辑是线程安全的并且可以并行进行。切换到Parallel.Foreach()或将Join()从辅助函数中移出时要非常小心。

+0

我很好奇,在评论中@Jeroem Mostert类型“小心你的逻辑必须是线程安全的” 如果我想使用Parallel.ForEach,逻辑线程的安全性究竟是什么? – ThunD3eR

+0

@ Ra3IDeN确保您的数据不会被两个线程同时更改。 –

+0

好的,我发布了Parallel.ForEach,并且它运行得很快。尽管一些断点从来没有被打到哪种让我担心代码从未到达目的地的问题。我发现所有的错误,并且eveyrhting没问题,但是某些部分的断点根本不会受到影响。使用这个时我缺少的东西? – ThunD3eR