【问题标题】:Passing in an anonymous delegate to a thread...why does this work?将匿名委托传递给线程......为什么会这样?
【发布时间】:2010-11-30 20:48:37
【问题描述】:

在我的程序中,我们将需要在四个线程中查看的大量数据拆分。

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

我们的编码标准要求我们符合 StyleCop,事实上,StyleCop 要求以下:

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

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

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

我查看了 ThreadStart 和 ParameterizedThreadStart 对象,但我无法弄清楚如何使用这些对象中的任何一个来完成我需要完成的工作。

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

感谢您的帮助,

寻找者

【问题讨论】:

    标签: c# .net multithreading stylecop anonymous-delegates


    【解决方案1】:

    您可以使用 lambda 表达式代替 delegate 关键字:

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

    【讨论】:

      【解决方案2】:

      你有两个选择:

      • 忽略 StyleCop 警告(推荐)
      • 改成new ThreadStart(delegate { ... })

      解释:

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

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

      【讨论】:

      • 从您的描述来看,风格警察规则通常听起来像是一个愚蠢的想法。它的描述是“当匿名方法不包含任何方法参数时,参数周围的括号是可选的。”也会误导。
      【解决方案3】:

      StyleCop 很笨。

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

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

      如果您想让 StyleCop 开心编译您的代码,这是一种选择:

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

      这是另一个:

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

      但我的建议是向 StyleCop 的作者 LART 提出这个荒谬的规则。

      【讨论】:

      • 请注意,这两个选项将(AFAIK)编译相同。
      • 是的,他们会的。后一种语法有效地使用了 C# 2 中引入的语法糖,当可以从上下文中推断出委托类型时,允许省略 new DelegateType(...) 构造。演员表提供了必要的上下文。
      • 拥有 codeplex 帐户的人可以在他们的论坛中发布此内容吗?
      猜你喜欢
      • 2015-10-09
      • 1970-01-01
      • 2018-05-07
      • 2014-11-19
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多