我找到了带有lambda表达式参数的启动线程的解决方案。
Thread amazonBuy1 = new Thread(() => amazon.Buy("Lego", visa, dhl));
所以,我的问题是 - lambda究竟是如何工作的? 在谈到线程参数时,如何使用params给出一个不可能作为默认值的方法。
谢谢。
答案 0 :(得分:4)
请允许我演示编译器在那里做的事情:
class __horribleTypeName {
public Something amazon;
public SomethingElse visa;
public AnotherSomething dhl;
public void __horribleMethodName() {
amazon.Buy("Lego", visa, dhl);
}
}
...
var __horribleLocalName = new __horribleTypeName();
__horribleLocalName.amazon = ... // etc
Thread amazonBuy1 = new Thread(__horribleLocalName.__horribleMethodName);
有意义吗?因此lambda内容成为编译器生成的方法的方法体。您在正文中访问的本地文件被提升到编译器生成的实例上的字段。请注意,此处使用的实际名称都是" unpronouncable" - 它们不能用C#表示 - 它们不是合法的C#标识符(但是是合法的IL标识符)。上面是一个简单的例子 - 编译器可以在某些情况下进行其他优化,包括将事物提升到重用的静态委托实例(当没有捕获上下文时)。另请注意,如果visa
或dlh
或amazon
是实例字段,则您捕获的内容为this
,而不是字段本身;所以它可能是:
class __horribleTypeName {
public YourType __this;
public void __horribleMethodName() {
__this.amazon.Buy("Lego", __this.visa, __this.dhl);
}
}
...
var __horribleLocalName = new __horribleTypeName();
__horribleLocalName.__this = this;
Thread amazonBuy1 = new Thread(__horribleLocalName.__horribleMethodName);
作为旁注:如果你想将状态传递给一个线程,那就有一个ParameterizedThreadStart
。
答案 1 :(得分:2)
如果我们接听您的电话:
verify='/etc/ssl/certs'
...并将它重构为两个单独的行,我们得到了这个:
Thread amazonBuy1 = new Thread(() => amazon.Buy("Lego", visa, dhl));
因此ThreadStart threadStart = () => amazon.Buy("Lego", visa, dhl);
Thread amazonBuy1 = new Thread(threadStart);
的构造函数根本不接受Thread
,"Lego"
,visa
参数 - 只需要一个dhl
委托。< / p>
委托是一个可用于调用方法的变量。在这种情况下,委托可以在调用时运行ThreadStart
。
这意味着线程可以启动,然后从新线程内部调用委托。
编译器完成所有魔术,允许amazon.Buy("Lego", visa, dhl)
和visa
捆绑在委托中。这被称为“封闭”。编译器生成一个委托,关闭两个变量。
答案 2 :(得分:0)
lambda表达式是一个匿名函数,它主要用于在LINQ中创建委托。简单地说,它是一个没有声明的方法,即访问修饰符,返回值声明和名称。方便。它是一种速记,允许您在要使用它的同一个地方编写方法。
来源: https://msdn.microsoft.com/en-GB/library/bb397687.aspx
您的Thread
会接受名为ThreadStart
或ParameterizedThreadStart
的代表。所以当你像这样使用lambda时,你就可以动态创建委托方法。