【问题标题】:Parallel.ForEach doesn't compile in VS2013, but works in VS2015Parallel.ForEach 在 VS2013 中无法编译,但在 VS2015 中有效
【发布时间】:2017-07-02 21:23:09
【问题描述】:

我正在使用这个example 创建分区,并且在我的 VS2015 应用程序中运行良好。我尝试将代码移动到VS2013,使用4.5.2框架,现在这行代码出现错误:

VS2013 12.0.40629.00 更新 5

body: (source, state, local) => 

错误 5 委托 'System.Func,System.Threading.Tasks.‌​ParallelLoopState,lo‌​ng,AnonymousType#1,A‌​nonymousType#1>' 不接受 3 个参数

我发现了这个问题:Whats wrong in this Parallel.For Code?,非常相似。但这似乎并不是同一个问题。

建议的答案在 2013 年没有任何语法错误,但不使用分区,所以我不确定如何使我的代码适应那个。并且建议添加三个参数,我的已经有了三个参数。

这是我的代码的简化版本:

public void NearLinkParallelGeneration(avl_range avl_pending)
{
    var parallelOptions = new ParallelOptions
    {
        MaxDegreeOfParallelism = Environment.ProcessorCount + 2
    };

    var partitions = Partitioner
                        .Create(
                            fromInclusive: avl_pending.begin,
                            toExclusive: avl_pending.end,
                            rangeSize: 100
                        )
                        .GetDynamicPartitions();

    Parallel.ForEach(
        source: partitions,
        parallelOptions: parallelOptions,
        localInit: () => 
        {
            NpgsqlConnection conn = new NpgsqlConnection(strConnection);
            NpgsqlCommand cmd = new NpgsqlCommand();

            conn.Open();

            return new { Connection = conn, Command = cmd };
        },
        body: (source, state, local) => -- HERE IS THE ERROR
        {
            return local;
        },
        localFinally: local =>
        {
            local.Connection?.Dispose();
            local.Command?.Dispose();
        }
    );

错误图片:

【问题讨论】:

  • @twoleggedhorse 你知道我已经链接了那个答案吗?而且我的代码已经在使用这三个参数。但是在那个答案中不使用分区,而我的确实如此。所以不确定如何将我的代码转换为那个。此外,我的代码已经在 VS-2015 中运行
  • @twoleggedhorse:您提出的副本甚至不涉及相同的方法。这个问题和答案属于Parallel.For(),而这个问题和答案属于Parallel.ForEach()。此外,该问题和答案涉及 API 的 CTP(预览版)版本中存在但在最终版本中已删除的方法重载,而此问题涉及绝对确实存在存在的方法重载并且自从 API 发布以来。请删除您的投票结束,因为建议的重复是一个错误的选择。

标签: c# visual-studio-2013 visual-studio-2015 parallel.foreach


【解决方案1】:

我没有安装 VS2013,所以我无法重现您的问题。但是,编译器似乎对选择哪个重载感到困惑。

您正在复制的代码使用ForEach() 方法的Parallel.ForEach<TSource, TLocal> Method (IEnumerable<TSource>, ParallelOptions, Func<TLocal>, Func<TSource, ParallelLoopState, TLocal, TLocal>, Action<TLocal>) 重载。

您收到的错误消息清楚地表明编译器已为您的调用选择了Parallel.ForEach<TSource, TLocal> Method (IEnumerable<TSource>, ParallelOptions, Func<TLocal>, Func<TSource, ParallelLoopState, Int64, TLocal, TLocal>, Action<TLocal>) 重载。也就是说,预计委托不仅会收到 sourcestatelocal 值,还会收到当前项目的 index

目前缺乏在 VS2013 中测试代码的能力,我不完全确定为什么编译器选择了错误的重载。但我认为这可能与'Delegate 'System.Action' does not take 0 arguments.' Is this a C# compiler bug (lambdas + two projects)? 中描述的问题有关。答案是,是的,这是一个编译器错误,因为延迟缓存在编译器方面的重载元数据出错。

如果确实如此,您应该能够通过为 lambda 参数提供显式类型来解决此问题。不幸的是,在您的情况下,您对 TLocal 类型参数使用匿名类型。所以你没有那个选项,除非你愿意声明一个命名类型来代替匿名类型。

另一种选择是放弃并遵循编译器对您所调用的重载的想法。同样,我不能自己测试这个,但我希望这会起作用:

Parallel.ForEach(
    source: partitions,
    parallelOptions: parallelOptions,
    localInit: () => 
    {
        NpgsqlConnection conn = new NpgsqlConnection(strConnection);
        NpgsqlCommand cmd = new NpgsqlCommand();

        conn.Open();

        return new { Connection = conn, Command = cmd };
    },
    body: (source, state, index, local) // just add the 'index' parameter
    {
        return local;
    },
    localFinally: local =>
    {
        local.Connection?.Dispose();
        local.Command?.Dispose();
    }
);

【讨论】:

  • 不幸的是不起作用,现在说不支持4个参数。 2 或 1 个参数也是如此。现在我想也许没有使用正确的 Paraller.ForEach?也许我需要更改参考?不知道这是否有帮助,但 VS 说正在使用这个重载 version
  • 我对匿名类型不熟悉,你能告诉我如何让它们命名类型吗?
  • “VS 说正在使用这个重载版本” -- 哪个 VS 版本这么说?该图像显示了您想要的过载,即this one。如果添加 index 参数没有帮助,那么我猜你被命名类型卡住了。您需要做的就是,在方法本身之外,声明一个像class CxCmd { public NpgsqlConnection { get; set; } public NpgsqlCommand { get; set; } } 这样的类型,然后在localInit lambda 中,return new CxCmd { Connection = conn, Command = cmd };
  • 你可以给命名类型取任何你想要的名字...我只是为了方便使用CxCmd
  • 我在家里用 VS 2013,在办公室用的是 2015。
猜你喜欢
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多