将一个匿名委托传递给一个线程......为什么这个工作?

see*_*dge 6 .net c# multithreading stylecop anonymous-delegates

在我的程序中,我们分割了大量需要在四个线程中查看的数据.

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); });
Run Code Online (Sandbox Code Playgroud)

我们的编码标准要求我们符合StyleCop标准,StyleCop要求如下:

SA1410:从匿名方法中删除括号,因为委托的参数列表为空.

这样做会给我这个编译错误:

以下方法或属性之间的调用不明确:'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)'和'System.Threading.Thread.Thread(System.Threading.ThreadStart)'

我查看了ThreadStart和ParameterizedThreadStart对象,我无法弄清楚如何获得我需要完成的任何这些对象.

我的问题:匿名代表如何工作?他们编译到什么?最后,我将不得不在没有匿名代表的情况下工作,但我不知道从哪里开始.

谢谢您的帮助,

导引头

SLa*_*aks 7

您有两种选择:

  • 忽略StyleCop警告(推荐)
  • 将其更改为 new ThreadStart(delegate { ... })

说明:

没有括号(delegate { ... })的匿名方法具有隐式参数列表.编译器将为其提供匹配其所使用的委托所需的任何参数.(您的代码无法查看参数)
这在编写不使用其参数的匿名事件处理程序时非常有用; 它可以帮助您免于打字delegate(object sender, EventArgs e) { ... }.

但是,在调用Thread构造函数时,有两种不同的重载需要两种委托.
编译器无法知道您尝试创建哪种委托类型,因为您没有指定参数列表.


cdh*_*wie 5

StyleCop是迟钝的.

StyleCop暗示两种语法具有相同的含义. 这是完全错误的. 从委托中省略括号并不意味着"这不需要参数".这意味着"为我填写任何论据,因为无论如何我都不会使用它们."

由于两个不同的签名Thread:.ctor可用,每个签名采用不同的委托类型,编译器无法知道选择哪一个,因为任何一个都可以.添加括号会强制编译器选择ThreadStart变体,因为它是唯一具有与您的匿名方法兼容的委托类型的签名.

如果你想让StyleCop满意并且你的代码已经编译,那么这是一个选择:

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

这是另一个:

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

但我的建议是LART StyleCop的作者介绍这个荒谬的规则.