【问题标题】:PLINQ WithDegreeOfParallelism Delay?PLINQ WithDegreeOfParallelism 延迟?
【发布时间】:2013-12-28 16:07:53
【问题描述】:

我想同时在多个对等点上执行基于网络的任务(可能会超时)。

所以我有以下代码:

Parallel.ForEach(hosts, i => SomeLongRunningNetworkTask(i));

我注意到从第六个任务开始执行延迟了约 1 秒。

所以我把代码改成:

hosts.AsParallel()
                .WithDegreeOfParallelism(64)
                .ForAll(i => result.Add(SomeLongRunningNetworkTask(i)));

但结果是一样的。

输出(在四核上):

Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 1025,06 ms
Start: 2024,12 ms
Start: 3024,17 ms
Start: 4024,23 ms
Start: 5024,29 ms
...

有没有一种简单的方法来使用 PLINQ 而不会出现这种奇怪的行为,或者我错过了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplicationParallelTest
{
    class Program
    {
        private DateTime Started { get; set; }

        static void Main(string[] args)
        {
            // for testing: All Subnet IP's: 
            var ips = new List<IPAddress>();
            for(int i=1 ; i< 255 ;i++)
                ips.Add( IPAddress.Parse( "192.168.10." + i ));

            var result = new Program().ExecuteAll(ips);
        }

        private List<Object> ExecuteAll(List<IPAddress> hosts)
        {
            Started = DateTime.Now;
            var result = new List<Object>();

            //Parallel.ForEach(hosts, i => SomeLongRunningNetworkTask(i));
            hosts.AsParallel()
                .WithDegreeOfParallelism(64)
                .ForAll(i => result.Add(SomeLongRunningNetworkTask(i))
                );

            return result;
        }

        private Object SomeLongRunningNetworkTask(Object o)
        {
            Console.WriteLine("Start: " + DateTime.Now.Subtract(Started).TotalMilliseconds.ToString("F2") + " ms");
            Thread.Sleep(60 * 1000);
            Console.WriteLine("End: " + DateTime.Now.Subtract(Started).TotalMilliseconds.ToString("F2") + " ms");
            return new Object();
        }
    }
}

【问题讨论】:

  • WithDegreeOfParallelism 并不意味着它会使用那么多线程。它仅用于设置上限(TPL 将根据您的系统配置决定使用多少 thrad)。
  • 使用 Thread.Sleep() 不会产生可用于真实代码的结果。如果要优化网络代码,请使用该网络。

标签: c# .net plinq


【解决方案1】:

当您的线程调用Thread.Sleep 时,它们正忙于等待,无法处理您的其他主机。 我的猜测是ThreadPool 意识到它需要更多资源并创建更多线程。

尝试将ThreadPool.SetMinThreads 设置为更大的数字后运行测试。

编辑: 正如@henk 评论的那样。这几乎从来都不是一个好主意。

【讨论】:

  • SetMinThreads 是解决问题的直接方法。然而,它是一种生硬的、应用广泛的工具,可能不是最好的解决方案。
猜你喜欢
  • 2012-08-14
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2015-03-08
相关资源
最近更新 更多