ThreadPool.QueueUserWorkItem和Parallel.ForEach之间的区别?

时间:2013-02-27 21:27:31

标签: c# multithreading windows-services parallel.foreach queueuserworkitem

以下两种方法之间的主要区别是什么:

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文件发送到相应的客户端。

谢谢!

1 个答案:

答案 0 :(得分:22)

主要区别在于功能性。 Parallel.ForEach将阻止(按设计),因此在处理完所有对象之前它不会返回。你的foreach排队线程池线程工作会将工作推送到后台线程,而不是阻塞。

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

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

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

objClientList.AsParallel().ForAll(SendFilesToClient);

在性能和功能方面,这与Parallel.ForEach方法非常相似。