2012-04-25 138 views
0

當我跑這段代碼使用.Net 4.0和.Net 4.5的任務?

 private void button1_Click(object sender, EventArgs e) 
    { 
     Start(sender, e); 
    } 

    private void Start(object sender, EventArgs e) 
    { 
     for (int i = 0; i < 5; i++) 
     { 
      System.Threading.Tasks.Task.Factory.StartNew(() => dosomething(i)); 
      Debug.WriteLine("Called " + i); 
     } 
     Debug.WriteLine("Finished"); 

    } 
    public void dosomething(int i) 
    { 
     Debug.WriteLine("Enters " + i); 
     lock (this) 
     { 
      Debug.WriteLine("Working " + i); 
      Thread.Sleep(100); 
     } 
     Debug.WriteLine("Done " + i); 
    } 

輸出與.NET版本4.0和4.5的不同。用4.0重複5,我可以看到i的原因值在執行一些任務之前移動到5,但與4.5相同的代碼顯示不同的輸出。

(輸出運行與2010年VS .NET 4.0)

Called 0 
Called 1 
Enters 1 
Working 1 
Called 2 
Called 3 
Called 4 
Finished 
Enters 0 
Done 1 
Enters 5 
Working 0 
Working 5 
Done 0 
**Enters 5 
Working 5 
Done 5 
Enters 5 
Done 5 
Working 5 
Done 5** 

但是當我與.NET 4.5(VS 2011測試版)的結果是,跑出

(輸出運行與VS 2011測試。 Net 4.5)

Enters 0 
Working 0 
Called 0 
Called 1 
Enters 2 
Called 2 
Enters 2 
Enters 3 
Called 3 
Called 4 
Finished 
Done 0 
Working 2 
Enters 5 
Done 2 
Working 3 
Done 3 
Working 5 
Done 5 
Working 2 
Done 2 

我看不到使用CLR 4.5下的任務所做的更改?任何人都可以點我.Net 4.5有什麼變化。

回答

0

您的代碼有race condition。這意味着它可以以各種方式運行,具體取決於操作的確切順序。

任何小的改變都會影響操作的順序,所以在不同版本的框架下,你的代碼行爲會不一樣。實際上,當我爲同一版本的.net運行多次時,我預計它的行爲會有所不同。

+0

我不會爲命令而煩惱,我只看着我的價值是與.NET 4.0的線程共享,但與.NET 4.5不兼容。 – murali 2012-04-25 17:19:32

+0

在這兩種情況下,'Start()'中的''i'變量是共享的,究竟發生什麼取決於操作順序。 – svick 2012-04-25 18:31:38

+0

感謝您的時間...所以,您的觀點是4.5沒有變化,結果是不同的,因爲操作順序?我不這麼認爲,我說這個是什麼原因?如果您觀察輸出操作的順序,則只會在暫停後短暫地看到該值受到影響。我已經測試了多次和所有的時間,順序是不同的,但結果是相同的如上所示... – murali 2012-04-26 10:52:12

1

您的代碼有競爭條件。假設循環在任何任務開始之前完成執行。這完全有可能。

然後我會在全部任務中有一個值爲5的值。這是錯誤。

解決方案:將我複製到一個循環局部變量並在任務的lambda中使用此局部變量。

+0

感謝您的回覆,我確實同意更改代碼System.Threading.Tasks.Task.Factory.StartNew((對象o)=> dosomething(i),i);確實工作正常,我的問題不是如何使它工作,而是對CLR 4.5做了哪些改變? – murali 2012-04-26 10:46:24

+0

@murali這個問題沒有意義。順序是簡單的未定義的,並且不需要在同一版本的運行時的不同運行之間保持一致。 – CodesInChaos 2012-04-26 10:59:50

+0

我想新的CLR在啓動任務時效率更高。因爲(不確定性)的順序改變了。順便說一句,這不是未定義的行爲。它是明確的但不確定的。 – usr 2012-04-26 11:03:38