【问题标题】:Code runs in parallel in LinqPad, but not in Console App...why?代码在 LinqPad 中并行运行,但不在控制台应用程序中...为什么?
【发布时间】:2016-05-18 09:16:53
【问题描述】:

我需要针对不同的日期范围对单个 Web 服务进行一系列调用,并生成一个串联的结果集。尽管我在这方面的经验有限,但我想同时拨打电话以加快流程。

我尝试了几种技术,但根据执行时间,当我在 Visul Studio 控制台应用程序中运行代码调用时,它们会继续按顺序运行。我的意思是,如果一个月日期范围内的调用需要 15 秒,那么其中三个本应并行运行的一个月调用需要 45 秒。

但真正让我吃惊的是:我开始在 LinqPad 中运行完全相同的代码以便于调试。瞧,在 LinqPad 中,相同的代码确实是并行运行的!调用 3 个月总共需要大约 15 秒!

现在我正在摸不着头脑,这怎么可能。我尝试将 LinqPad 版本复制到一个新的 conole 项目中(以仔细检查两个版本中的所有内容是否完全相同),但它不会改变行为。

如果有任何建议,我将不胜感激。我不确定哪个代码与问题相关,但我在下面包含了 Web 服务调用类的略微简化版本:

class Importer
{
    public List<FuncDetails> GetAllData(DateRange[] intervals)
    {
        Task<List<PropFuncsType>>[] tasks = intervals
            .ToList()
            .Select(interval => GetDataForIntervalAsync(interval.StartDate, interval.EndDate))
            .ToArray();

        var result = new List<ResultDataTable>();
        Task.Factory.ContinueWhenAll(tasks, results => { foreach (var output in results) { result.AddRange(output.Result); } })
        .Wait();

        return result.SelectMany(x => x.ResultDataRow).ToList();

    }

    async static private Task<List<ResultDataTable>> GetDataForIntervalAsync(DateTime startDate, DateTime endDate)
    {
        var service = new ServiceClient();

        var result = await service.getDataAsync(new ServiceRequest()
            {
                startDate = string.Format("{0:yyyy-MM-dd}", startDate),
                endDate = string.Format("{0:yyyy-MM-dd}", endDate)
            }
        );

        return result.ServiceResponse.ToList();
    }
}

【问题讨论】:

  • 你检查过ServicePointManager.DefaultConnectionLimit吗?
  • 就是这样! ServicePointManager.DefaultConnectionLimit 实际上是一个全局变量,并且 LinqPad 主机必须在我的代码之外将它设置为一个高值。这两天我一直在为此头疼。请将您的评论作为答案,以便我给予您适当的信任!

标签: .net task-parallel-library linqpad


【解决方案1】:

尝试在控制台应用启动时将ServicePointManager.DefaultConnectionLimit 设置为int.MaxValue。这是 .NET 上 HTTP 限制的常见但微妙的原因。

(大概,LINQPad 已经做了类似的事情)。

【讨论】:

  • 从默认值 (2) 增加值正是答案,尽管我最初确实发现将其设置为远远超过 24 的值(在我的情况下)会无意中导致拒绝服务攻击在我自己的网络服务提供商上。 :-) 强大的力量带来了巨大的责任,我认为在我的调用代码中明确地管理这种限制可能会更好。干杯。
  • 我有一个代码在 LINQPad 中花费了大约 3 秒,在控制台应用程序中花费了大约 60 秒。我试图在我的控制台应用程序中设置ServicePointManager.DefaultConnectionLimit = int.MaxValue;,但不起作用。有什么想法吗?
  • @MehdiDehghani:您应该将代码作为单独的问题发布。
猜你喜欢
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多