20

两个以下方法之间的主要区别是什么:ThreadPool.QueueUserWorkItem和Parallel.ForEach之间的区别?

ThreadPool.QueueUserWorkItem

Clients objClient = new Clients(); 
    List<Clients> objClientList = Clients.GetClientList(); 

    foreach (var list in objClientList) 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(SendFilesToClient), list); 
    } 

System.Threading.Tasks.Parallel的ForEach

Clients objClient = new Clients(); 
    List<Clients> objClientList = Clients.GetClientList(); 

    Parallel.ForEach<Clients>(objClientList, list => 
    { 
     SendFilesToClient(list); 
    }); 

我是新来的多线程,并且想知道每种情况下会发生什么(就执行过程而言)什么是多线程,线程的每种方法?帮助我可视化两个过程。

SendFilesToClient:从数据库获取的数据,转换为Excel和Excel文件发送到相应的客户端。

谢谢!

回答

21

主要区别是功能性。 Parallel.ForEach将会阻塞(通过设计),所以在所有对象都被处理之前它不会返回。您的foreach排队线程池线程工作将推后工作到后台线程,而不是阻止。

此外,Parallel.ForEach版本还有另一个主要优势 - 未处理的异常将被推回到调用站点,而不是留在未处理的ThreadPool线程上。

一般来说,Parallel.ForEach会更有效率。这两个选项都使用ThreadPool,但Parallel.ForEach执行智能分区以防止过度读取并减少调度程序所需的开销量。单个任务(将映射到ThreadPool线程)被重用,并有效地“集中”以降低开销,特别是如果SendFilesToClient是一个快速操作(在这种情况下,它不会是真的)。

请注意,您还可以,作为第三个选项,请使用PLINQ:

objClientList.AsParallel().ForAll(SendFilesToClient); 

这将是非常相似的Parallel.ForEach方法在性能和功能方面。

+0

感谢您的详细解释@Reed。两个问题:1)为什么block很重要(如果你可以回答我的代码,这会很好)? 2)进一步扩展主要问题,使用PLINQ比使用Parallel.ForEach有什么好处? – Learner 2013-02-27 21:43:24

+0

@Mhirir 1)阻塞是不同的。您正在运行的线程将在运行下一行代码之前等待Parallel.ForEach完成,但foreach/TP.QUWI代码不会等待。 2)没有优势,除了可能更简单的代码了解 – 2013-02-27 21:59:02

+0

伟大的,再次感谢解释! – Learner 2013-02-27 22:02:11

相关问题