2013-05-04 51 views
1

我目前正在嘗試通過使用任務來利用.Net 4.0中的並行線程來進行一些性能優化。瞭解System.Threading.Tasks行爲

我做了三個方法,返回一些對象的集合或只是一個對象。 我們稱它們爲MethodA,MethodB和MethodC。

MethodB內部我有一個長時間的延遲 - 約5-7秒。

var person = new Person(); 

person.A = Task.Factory.StartNew(() => Mystatic.MethodA()).Result; 
person.B = Task.Factory.StartNew(() => Mystatic.MethodB()).Result; 
person.C = Task.Factory.StartNew(() => Mystatic.MethodC()).Result; 

現在我期待person.A和person.C屬性設置/ person.B之前填充,但我有困難的測試/調試它來驗證我的假設。

我已經在所有三個屬性中添加了一個平行手錶,但通過調試並沒有爲我闡明一些事情。

此外,如果我正在填充一個主要對象,這也是我優化對方法的多個調用的正確方法嗎?

在我的情況下,我有5-7種不同的方法來收集數據,並且我想讓它們平行,因爲它們中的一些相對耗時。

+1

旁註:只需編寫「Task.Factory.StartNew」。 – usr 2013-05-04 19:34:36

+0

不錯 - 這簡單得多:) – codingjoe 2013-05-04 19:59:13

回答

1

你的假設是錯誤的。任務的Result屬性將有效等待任務完成 - 因此,A,B,C將按該順序進行分配。此外,這將打破創建異步任務的目的。

的一種方法是,你可以在所有三個任務使用Task.WaitAll,然後從每個任務A,B分配結果,C

你也可以使用異步/ AWAIT如果你有VS2012 - 你仍然可以 - 如果要並行執行在一定程度上

person.A = await Task.Run(() => Mystatic.MethodA()); 
person.B = await Task.Run(() => Mystatic.MethodB()); 
person.C = await Task.Run(() => Mystatic.MethodC()); 

它仍然是順序:使用http://nuget.org/packages/Microsoft.Bcl.Async/

然而明白,異步/的await不會,如果你這樣做開始並行3個任務目標.NET 4.0你可以這樣做:

Task tA = Task.Run(() => Mystatic.MethodA()); 
Task tB = Task.Run(() => Mystatic.MethodB()); 
Task tC = Task.Run(() => Mystatic.MethodC()); 

person.A = await tA; 
person.B = await tB; 
person.C = await tC; 
+0

是的,我得到了一個同事解釋的部分。我的擔心就是這樣,各個線程並行工作,不連續。 – codingjoe 2013-05-08 18:38:36

4

依靠時間是原則上的錯誤,因爲時間不會得到保證,尤其是不會在真實的詞條件下。如果您需要確保它們已完成,您應該在任務上應用適當的等待。或者使用C#5.0異步等待或繼續。

總之,不要巧合編程。通過施工使你的程序正確。

+0

+1。作爲旁註,如果對象在創建後需要(冗長)初始化,我會包含一個'公共靜態任務 CreateAsync()'方法,並且(可能)使構造函數成爲私有的。但我離題:) – 2013-05-04 19:37:42

+0

這是正確的答案。但是,如果你真的只是想用調試器來測試你的懷疑(也是一個有問題的做法),你可以在每個屬性設置器中做一個簡單的Debug.Write,或者可能在每個設置器中設置一個斷點。 – Gjeltema 2013-05-04 19:43:50

+0

通過調試,我打算在每個屬性上製作手錶,並在示波器的末端設置斷點,並留意手錶。 我會嘗試嘗試await /異步,但這不是我正在使用的框架工作版本:( – codingjoe 2013-05-04 19:56:03