当前位置:  开发笔记 > 前端 > 正文

使用异步委托或ThreadPool.QueueUserWorkItem进行大规模并行化?

如何解决《使用异步委托或ThreadPool.QueueUserWorkItem进行大规模并行化?》经验,为你挑选了2个好方法。

我有一个.NET应用程序,在批量导入中处理大约300,000条记录,每条记录需要几秒钟,所以我想并行化这个.在下面的代码中,ProcessWithAnsycDelegates()和之间有什么区别ProcessWithThreadPool()

public class ResultNotification
 { public EventHandler event Success;
   public EventHandler event Fail;
   internal void Notify(bool sucess) {if (success) Success(); else Fail();}
 }

public static class Processor
 { public ResultNotification ProcessWithAnsycDelegates(Record record)
    { var r = new ResultNotification();
      Func processRecord=new RecordProcessor().ProcessRecord;
      processRecord.BeginInvoke
                     ( record
                      ,ar => result.Notify(processRecord.EndInvoke(ar))
                      ,null); 
      return r;    
    }

   public ResultNotification ProcessWithThreadPool(Record r)
    { var r  = new ResultNotification();
      var rp = new RecordProcessor();
      ThreadPool.QueueWorkUserItem(_=>result.Notify(rp.ProcessRecord(r)));
      return r;
    }
 }

Thomas Bratt.. 7

这个问题的字面答案是两者都使用线程池,因此如果性能是唯一的考虑因素,差异并不大.

如果问题实际上是关于获得最佳性能,那么知道使用线程池确实存在问题可能会有所帮助.这些包括:

锁定工作队列上的争用

过多的上下文切换.如果你有2个CPU和一系列工作项,那么25个线程并没有真正帮助.最好有2个线程,每个CPU一个

可能值得调查TPL和PLINQ:

并行LINQ在多核处理器上运行查询

并行性能优化多核机器的管理代码

在Visual Studio的下一版本中改进了对并行性的支持

他们给出的TPL使用的一个例子是:

for (int i = 0; i < 100; i++) { 
  a[i] = a[i]*a[i]; 
}

至:

Parallel.For(0, 100, delegate(int i) { 
  a[i] = a[i]*a[i]; 
});


chadmyers.. 6

在这种情况下,并不是很多,因为他们都使用引擎盖下的线程池.我会说QueueUserWorkItem()更容易阅读,看看与BeginInvoke有什么关系.

此链接可能有所帮助.这是较旧的信息,但仍然大多适用 http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml



1> Thomas Bratt..:

这个问题的字面答案是两者都使用线程池,因此如果性能是唯一的考虑因素,差异并不大.

如果问题实际上是关于获得最佳性能,那么知道使用线程池确实存在问题可能会有所帮助.这些包括:

锁定工作队列上的争用

过多的上下文切换.如果你有2个CPU和一系列工作项,那么25个线程并没有真正帮助.最好有2个线程,每个CPU一个

可能值得调查TPL和PLINQ:

并行LINQ在多核处理器上运行查询

并行性能优化多核机器的管理代码

在Visual Studio的下一版本中改进了对并行性的支持

他们给出的TPL使用的一个例子是:

for (int i = 0; i < 100; i++) { 
  a[i] = a[i]*a[i]; 
}

至:

Parallel.For(0, 100, delegate(int i) { 
  a[i] = a[i]*a[i]; 
});



2> chadmyers..:

在这种情况下,并不是很多,因为他们都使用引擎盖下的线程池.我会说QueueUserWorkItem()更容易阅读,看看与BeginInvoke有什么关系.

此链接可能有所帮助.这是较旧的信息,但仍然大多适用 http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有