6

我有一个 .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<Record,bool> 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;
    }
 }
4

2 回答 2

7

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

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

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

可能值得研究 TPL 和 PLINQ:

他们给出的使用 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]; 
});
于 2008-10-11T21:08:29.203 回答
6

在这种情况下,不是很多,因为他们都使用引擎盖下的线程池。我会说 QueueUserWorkItem() 更容易阅读和查看与 BeginInvoke 相比发生了什么。

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

于 2008-10-10T18:36:29.323 回答