'Passing in an anonymous delegate to a thread...why does this work?

In my program, we split up a large amount of data that needs to be looked over across four threads.

Thread one = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); });
Thread two = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[1], param2, param3, param4, param5); });
Thread three = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[2], param2, param3, param4, param5); });
Thread four= new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[3], param2, param3, param4, param5); });

Our coding standards require that we are StyleCop compliant, as it were, and StyleCop demands the following:

SA1410: Remove the parenthesis from the anonymous method, since the delegate's parameter list is empty.

Doing that gives me this compiler error:

The call is ambiguous between the following methods or properties: 'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)' and 'System.Threading.Thread.Thread(System.Threading.ThreadStart)'

I've looked into the ThreadStart and ParameterizedThreadStart objects and I just can't figure out how to get what I need done with either of those objects.

My question: how do the anonymous delegates work? What do they compile down to? In the end, I will have to get this working without the anonymous delegates, but I don't know where to begin.

Thanks for the help,

Seeker



Solution 1:[1]

StyleCop is dumb.

StyleCop is implying that the two syntaxes have the same meaning. This is completely wrong. Omitting the parentheses from a delegate does not mean "this takes no arguments." It means "fill in any arguments for me, because I won't be using them anyway."

Since two different signatures of Thread:.ctor are available, each taking a different delegate type, the compiler cannot know which one to pick, since it would be just fine with either one. Adding the parentheses forces the compiler to pick the ThreadStart variant, since it is the only signature with a delegate type compatible with your anonymous method.

If you want to make StyleCop happy and have your code compile, this is one option:

Thread one = new Thread(new ThreadStart(delegate { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); }));

This is another:

Thread one = new Thread((ThreadStart) delegate { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); });

But my suggestion would be to LART the StyleCop authors for introducing this ridiculous rule.

Solution 2:[2]

You could use a lambda expression instead of the delegate keyword:

Thread one = new Thread(() => NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 seekerOfKnowledge
Solution 2 Joe White