2012-04-05 36 views
-2

我正在嘗試使用TPL。它不應該正常工作,我在我的行動主體內定義的所有東西都是完全獨立的?似乎並非如此。有人能指引我走向正確的方向嗎? 基本上我想要做的就是多次執行一個方法。這個方法總是創建一個具有將要執行的run方法的對象的實例。C#TPL - 隔離?

+0

根本不清楚你想要什麼。 – Aliostad 2012-04-05 13:12:06

+0

您應該發佈有問題的代碼,以及實際結果,以及您的預期結果 - 以及爲什麼您認爲它們不應該有所不同。 – vcsjones 2012-04-05 13:13:59

+0

會準備一個簡單的例子。 – user1313693 2012-04-05 13:15:35

回答

1

雖然你沒有提供任何代碼,但通靈調試表明你已經發現了lambda的一個主要特性,即:閉包。 (或根據您的新評論:同步,或者說缺乏)

考慮:

int x = 0; 
Action y =() => Console.WriteLine("{0}", x++); 
Action z =() => Console.WriteLine("{0}", --x); 

兩個yz指的x同一個實例。現在,這是一個簡單的例子,但有for環或foreach考慮的情況:

for (int i = 0; i < 10; ++i) 
{ 
    Task.Factory.StartNew(() => Console.WriteLine("{0}", i)); 
} 

所有10個任務將引用同一個變量i!實際上,他們可能都會收到與i相同的。這是因爲它們都在內存中圍繞相同變量關閉。

如果你想他們是獨立的,他們需要獨立的變量及其封閉:

foreach (var datum in data) 
{ 
    // Because myDatum is local to *each* loop iteration, 
    // each Task will receive its own variable. The same 
    // strategy applies to for-loops. 
    var myDatum = datum; 
    Task.Factory.StartNew(() => Frob(myDatum)); 
} 

也許你碰上了,再次SANS代碼另一種情況,是數據結構的sychronization。除非您使用的是concurrent data structure,沒有同步開箱:

var bad = new List<int>();   // No implicit thread safety 
var good = new ConcurrentBag<int>(); // Thread safe access 

Parallel.For(0, 1000, x => bad.Add(x)); 
Parallel.For(0, 1000, x => good.Add(x)); 

結合,我們已經討論了兩個問題,你可以看到你會遇到的問題,用下面的貌似正確的代碼?

var counts = new Dictionary<int, int>(); 
for (int i = 0; i < 1000; ++i) 
{ 
    // How many ways can this fail? One should be enough. 
    Task.Factory.StartNew(
     () => 
     { 
      counts[i] = GetCounts(i); 
     }); 
} 
+0

謝謝,我明白這一點,在我的情況下,它更簡單,因爲我不使用循環變量。 (int i = 0; i <10; ++ i) { Task.Factory.StartNew( ()=> { } var person = new Person() ; person.LoadInfoFromFile(); person.CheckAnything(); }); } – user1313693 2012-04-05 13:28:49

+0

對不起,我有編輯問題。將解決它。這個例子不應該完全獨立嗎? – user1313693 2012-04-05 13:29:57

+0

'LoadInfoFromFile'和'CheckAnything'是互斥的嗎?它應該非常接近你所擁有的;簡潔的細微變化是好的。但是使用線程技術,通常很難在沒有確切代碼的情況下知道每個問題。 – user7116 2012-04-05 13:30:02