2012-04-17 68 views
2

ReSharper重構了一個foreach循環我不得不這樣做。我想通過委託的BeginInvoke的產卵一堆線程使用不同的參數,存儲在一個列表,以及存儲IAsyncResults一個集合中:通過LINQ Select調用錯誤代碼產生新線程?

var asyncResults = mylist.Select(x => myDelegate.BeginInvoke(x, null, null)); 

我的本能反應是,這是不是一個好的做法。 BeginInvoke會導致產生新線程的副作用,並且傳遞給Select的函數不應導致副作用。

或者它可以,因爲我沒有改變調用線程中的任何東西?

+6

在你問自己「這是一個好習慣嗎?」之前問自己「這個代碼是否實現了我所描述的行爲?」它不是;這段代碼只是創建一個查詢對象。您創建了一個對象,意思是「我是從該列表中產生一系列異步結果的查詢」。 *正在*該查詢不會導致查詢*執行*。如果你想執行查詢並將結果存儲在一個集合中,你將不得不編寫更多的代碼。 – 2012-04-17 00:53:34

+0

它本身並沒有做任何事情,但在某些情況下它可能是合適的。然而,當你調用BeginInvoke時,我猜你通常希望線程在那裏和那裏開始,所以在這種情況下,LINQ查詢與foreach循環完全不同。 – Jimmeh 2012-04-17 17:13:56

回答

2

我覺得很難說這是否是一種好的做法,這取決於你如何使用它。

但是,像這樣使用LINQ時要記住的重要一點是Select()(以及其他許多LINQ方法)實際上並沒有迭代集合並執行代碼。只有在迭代所得到的集合時纔會發生這種情況,通常使用foreachToArray()

+0

是的,我認爲這可能是適當的,只有當你不介意沒有完全控制線程產生的時候。我忘記了LINQ的懶惰。 – Jimmeh 2012-04-17 17:09:07

3

這應該沒問題。創建一個新線程並不是真正的副作用。你沒有修改任何值。 BeginInvoke被調用,您正在存儲結果IAsyncResult

但是,你必須記住,沒有什麼會阻止。你必須自己管理所有事情的同步。