23

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

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

谢谢!

4

1 回答 1

24

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

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

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

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

objClientList.AsParallel().ForAll(SendFilesToClient);

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

于 2013-02-27T21:30:29.507 回答