我找到了帶有lambda表達式的參數的啓動線程解決方案。lambda是如何工作的? c#和線程
Thread amazonBuy1 = new Thread(() => amazon.Buy("Lego", visa, dhl));
所以,我的問題是 - lambda的工作原理是什麼? 當說到線程參數時,如何給出一個帶有參數的方法,它不可能作爲默認值。
謝謝。
我找到了帶有lambda表達式的參數的啓動線程解決方案。lambda是如何工作的? c#和線程
Thread amazonBuy1 = new Thread(() => amazon.Buy("Lego", visa, dhl));
所以,我的問題是 - lambda的工作原理是什麼? 當說到線程參數時,如何給出一個帶有參數的方法,它不可能作爲默認值。
謝謝。
如果我們把您的來電:
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
參數 - 它只需要一個ThreadStart
委託。
委託是一個可用於調用方法的變量。在這種情況下,委託人在調用時可以運行amazon.Buy("Lego", visa, dhl)
。
這意味着線程可以啓動,然後從新線程內部調用代理。
編譯器會執行所有的神奇的功能,允許visa
和dhl
捆綁在代理內部。這被稱爲「封閉」。編譯器生成一個代理,該代理關閉兩個變量的。
lambda表達式是一個匿名函數,它主要用於在LINQ中創建委託。簡而言之,它是一種沒有聲明的方法,即訪問修飾符,返回值聲明和名稱。方便。這是一種速記,允許您在要使用它的相同位置編寫一個方法。
來源:https://msdn.microsoft.com/en-GB/library/bb397687.aspx
你Thread
需要一個叫做ThreadStart
或ParameterizedThreadStart
委託。所以當你像這樣使用lambda時,你正在創建委託方法。
已編輯。是的,它呢?他問什麼lambda是什麼,它做了什麼。這正是它告訴他的。 – ThePerplexedOne
你的答案是不完整的,因爲它沒有描述爲lambda創建閉包的事實。 –
請允許我以證明編譯器有什麼:
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的內容成爲編譯器生成方法的方法體。您在本體內部訪問的本地文件被解壓到編譯器生成的實例中的字段。請注意,這裏使用的實際名稱都是「不可計數的」 - 它們不能用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
。
@ marc-gravell的答案的簡短版本是它創建了所謂的「閉包」,以便lambda方法運行時可以訪問'amazon','visa'和'dhl'變量。網上有很多很好的資源可以解釋如何使用閉包,而Marc的答案提供瞭如何在C#中實現它們的細節,如果您有興趣。 –