1

I'm using this example to create partitions and is working perfectly in my VS2015 app. I tried to move the code to VS2013, using 4.5.2 framework, and now have an error on this line of code:

VS2013 12.0.40629.00 Update 5

body: (source, state, local) => 

says

Error 5 Delegate 'System.Func<System.Tuple<long,long>,System.Threading.Tasks.‌​ParallelLoopState,lo‌​ng,AnonymousType#1,A‌​nonymousType#1>' does not take 3 arguments

I found this question: Whats wrong in this Parallel.For Code? which is very similar. But it does not appear to actually be the same problem.

The suggested answer doesn't have any syntax error in 2013 but doesn't use partitions, so I'm not sure how adapt my code to that one. And the recommendation is to add three parameters and mine already has three parameters.

This is a reduced version of my code:

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();
        }
    );

Error Image: https://i.stack.imgur.com/6Q5Ge.png

Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118
  • Possible duplicate of [Whats wrong in this Parallel.For Code?](https://stackoverflow.com/questions/5604082/whats-wrong-in-this-parallel-for-code) – twoleggedhorse Jul 02 '17 at 21:25
  • Possible duplicate of https://stackoverflow.com/questions/5604082/whats-wrong-in-this-parallel-for-code – twoleggedhorse Jul 02 '17 at 21:26
  • 2
    @twoleggedhorse Do you realize I already linked that answer? And my code is already using the three parameters. But In that answer doesnt use partitions, and mine does. So not sure how convert my code to that one. Also the fact my code already is working in VS-2015 – Juan Carlos Oropeza Jul 02 '17 at 21:26
  • @twoleggedhorse: your proposed duplicate doesn't even involve the same method. That question and answer pertain to `Parallel.For()`, while this one pertains to `Parallel.ForEach()`. In addition, that question and answer involve a method overload that existed in the CTP (preview) version of the API but which was removed for the final version, while this question involves a method overload that definitely _does_ exist and has since the API was released. Please remove your vote-to-close, as that proposed duplicate is an incorrect choice. – Peter Duniho Jul 03 '17 at 01:02

1 Answers1

1

I don't have VS2013 installed, so I'm unable to reproduce your problem. However, it appears that the compiler is getting confused about which overload to select.

The code you are copying uses the Parallel.ForEach<TSource, TLocal> Method (IEnumerable<TSource>, ParallelOptions, Func<TLocal>, Func<TSource, ParallelLoopState, TLocal, TLocal>, Action<TLocal>) overload of the ForEach() method.

The error message you're getting makes it clear that the compiler has selected the Parallel.ForEach<TSource, TLocal> Method (IEnumerable<TSource>, ParallelOptions, Func<TLocal>, Func<TSource, ParallelLoopState, Int64, TLocal, TLocal>, Action<TLocal>) overload for your call. That is, it's expected a delegate that will receive not just the source, state, and local values, but also the index for the current item.

Lacking the ability at the moment to test the code in VS2013, I'm not entirely sure why the compiler has selected the wrong overload. But I think it's possible it's related to the issue described at 'Delegate 'System.Action' does not take 0 arguments.' Is this a C# compiler bug (lambdas + two projects)?. With the answer being that, yes, it's a compiler bug, as result of deferred caching gone wrong of overload metadata on the part of the compiler.

If this is in fact the case, you should be able to work around the issue by providing explicit types for the lambda parameters. Unfortunately, in your case you are using an anonymous type for the TLocal type parameter. So you don't have that option, unless you are willing to declare a named type to use instead of the anonymous type.

Another option would be to give up and go along with the compiler's idea of what overload you're calling. Again, I can't test this myself, but I would expect this would work:

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();
    }
);
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • unfortunately doesnt work, now say doesnt support 4 parameters. The same go for 2 or 1 parameter. Now Im thinking maybe isnt using the right one Paraller.ForEach? Maybe I need change a reference? Dont know if this help but VS say is using this overload [version](https://i.stack.imgur.com/Si6YJ.png) – Juan Carlos Oropeza Jul 03 '17 at 02:13
  • Im not familiar with the anonymous type, can you show me how make them named type? – Juan Carlos Oropeza Jul 03 '17 at 02:40
  • _"VS say is using this overload version"_ -- which VS version says that? That image shows the overload you want, i.e. [this one](https://msdn.microsoft.com/en-us/library/dd783538(v=vs.110).aspx). If adding the `index` parameter doesn't help, then I guess you're stuck using a named type. All you need to do is, outside the method itself, declare a type like `class CxCmd { public NpgsqlConnection { get; set; } public NpgsqlCommand { get; set; } }`, and then in the `localInit` lambda, `return new CxCmd { Connection = conn, Command = cmd };`. – Peter Duniho Jul 03 '17 at 02:52
  • You can give the named type whatever name you want...I just use `CxCmd` for convenience. – Peter Duniho Jul 03 '17 at 02:52
  • Im using VS 2013 at home, at office I have 2015. – Juan Carlos Oropeza Jul 03 '17 at 04:22
  • Presumably you took [this screenshot](https://i.stack.imgur.com/Si6YJ.png) with only one or the other. That's what I am asking you about. Which version did that screenshot come from? By the way, why are you using VS2013 at home? You could use VS2017 Community for free, and this problem would like just go away. :) – Peter Duniho Jul 03 '17 at 04:23
  • Doesnt work with the named type neither. I will try download VS 2017 – Juan Carlos Oropeza Jul 03 '17 at 14:15
  • VS2017 is working ok. But I cant accept the answer because the problem on 2013 still persist. – Juan Carlos Oropeza Jul 04 '17 at 18:14
  • @Juan: I have finally had a chance to test your code in VS2013. I am unable to reproduce the error you describe. Your code example in the question is not a [mcve], and I now find that the code that is there is insufficient to reproduce the problem. So, while I'm sure there is a suitable work-around to whatever problem you are seeing, I cannot tell you what it is, because I do not yet have all the information required to reproduce the problem in the first place. Please fix the question. Also, please be more specific about what VS2013 version you are using. I am using 12.0.30723.00 Update 3. – Peter Duniho Jul 05 '17 at 07:17
  • Then the problem is with my installation of VS2013. Because the code in another project give me same error. `VS2013 12.0.40629.00 Update 5` – Juan Carlos Oropeza Jul 06 '17 at 11:48
  • That's not a logical conclusion. It _could_ be that you have a problem with your installation. But it would be unusual for an installation issue to lead to compiler errors like that. More likely, you simply haven't provided a good [mcve]. Note that just to get the code you posted to compile, I had to add types that you hadn't provided and make assumptions about the structure of the code. Compiler bugs can be sensitive to specific elements of the code; if I can't just copy/paste your code example, there's no assurance I'm testing the same exact code you are using. – Peter Duniho Jul 06 '17 at 15:38