2017-04-26 68 views
1

我正在閱讀有關在MSDN https://msdn.microsoft.com/en-us/library/ee372288(v=vs.110).aspx中創建多個前因的延續,並且很難理解代碼,這是他們使用的示例之一。我正在粘貼下面的代碼。TaskFactory.StartNew <TResult>方法(Func <Object,TResult>,Object)

for (int ctr = 1; ctr <= 10; ctr++) { 
    int baseValue = ctr; 
    tasks.Add(Task.Factory.StartNew((b) => 
     { 
     int i = (int) b; 
     return i * i; 
     }, 
     baseValue)); 
} 

當我讀到StartNew過載時,MSDN states

public Task<TResult> StartNew<TResult>(
    Func<object, TResult> function, 
    object state 
) 

參數

功能

類型:System.Func<Object, TResult>
一個函數委託,通過Task<TResult>返回未來結果。

狀態

類型:System.Object
由函數代表可以使用包含數據的對象。

具體而言,在他們的示例中,我不瞭解baseValue的用法,b作爲Object傳遞給該函數。

+0

'baseValue'是傳遞給提供給'StartNew'的委託的狀態對象。在這個例子中,baseValue將在循環執行時取值爲'ctr'。 [在另一張紙上遠離'StartNew'](https://blog.stephencleary.com/2013/08/startnew-is-dangerous.html) – JSteward

+0

b是什麼? –

+0

b是傳遞給lamda的參數,它大致相當於'void SomeFunc(int b)'。 – JSteward

回答

2

什麼是Func<object, TResult>?它是一種代表類型,它接受object並返回TResultTResult MethodName(object b)

下面的代碼樣本中的方法被內聯的λ,它接受object b並返回int構造(你可以看到的任務列表,它會返回int - List<Task<int>> tasks):

private int Square(object b) 
{ 
    int i = (int) b; 
    return i * i; 
} 

現在,您需要請致電這種方法,所以你傳遞第二個參數,baseValue。因此,對於從110的每個數字,您將得到它的平方:1 + 4 + 9 + 16 + 25 + 36 + 49 + 64 + 81 + 100,然後將其總結並得到385

所以,整個代碼可以讀作:

for (int ctr = 1; ctr <= 10; ctr++) 
{ 
    resultList.Add(Square(ctr)); 
} 

但整體計算將發生裏面的任務。
這可以被改寫爲:

for (int ctr = 1; ctr <= 10; ctr++) 
{ 
    // get a local copy of ctr 
    var baseValue = ctr; 
    // create a task which will get the square 
    tasks.Add(Task.Run(() => baseValue * baseValue)); 
    // or with a method introduction 
    tasks.Add(Task.Run(() => Square(baseValue))); 
} 

但在這種情況下,你會得到一個關閉,所以內部Task的代表將被重新創建每次用初始變形而不關閉比較(感謝@CoryNelson )。

注意,初始代碼是一個示例,並且不應該被用作圖案在生產代碼重現:它的塊的當前執行與.Result(這是確定僅作爲main方法不能async),它使用StartNew,其中can behave unexpectedly

一些有用的鏈接:

+1

我想補充一點,你會使用過載與捕獲lambda的原因是捕獲每次都會分配一個新的委託,而一個不捕獲的委託只會被分配一次。 –

+0

@CoryNelson謝謝,也補充說。 – VMAtm

+0

似乎lambda概念在我的腦海中並不清楚。 我希望看到, 'for(int ctr = 1; ctr <= 10; ctr ++){ob​​ject Object b = object(ctr); tasks.Add(Task.Factory.StartNew((B)=> { INT I =(int)的B; 返回I * I; }); }' –

相關問題