2012-02-16 23 views
2

我已經使用.net 4類System.Threading.Tasks遇到了一些strage行爲。這是最好的這個例子證明:任務報告IsCompleted,但仍然阻止結果?

var t = FunctionThatReturnsTaskAsync(); 
Trace.TraceInformation("Completed: " + t.IsCompleted); 
return t.Result; 

輸出:「完成:真」,但代碼(曾經在幾千運行),然後在t.Result塊永遠。它既不返回也不拋出異常。怎麼會這樣!

任務返回的是一些時間快速完成所以一點也不奇怪,它可以在第二行中完成。神祕的是爲什麼t.Result被阻止。

+2

這怎麼設定? – CodesInChaos 2012-02-16 10:00:29

+0

FunctionThatReturnsTaskAsync?它最終調用任務.Factory.StartNew(()=> {},CancellationToken.None)。 – 4ZM 2012-02-16 11:21:36

+2

奇怪。你能發佈一個展示問題的最小例子嗎? – CodesInChaos 2012-02-16 11:28:31

回答

1

異步方法本身會返回任務,您可能有任務<任務< T>>並且由於「異步」而內部任務在「正在完成」之前返回,並且外部任務<>認爲它已完成。

見斯蒂芬Toub對這個博客文章:

http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx

http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

允許我拉了相關報價:

要理解這個效果,我們需要記住異步方法如何操作。當你調用一個異步方法時,它開始同步運行。如果該方法沒有任何等待着它,或者如果所有的方法中的等待着的是在已經通過他們期待已久的時間完成awaitables,那麼該方法將完全同步運行。但是,當方法遇到第一個等待產生時,異步方法返回。在一個返回任務或任務,在這一點的任務返回或任務,它表示異步方法的執行的方法,和呼叫者可使用任務等待同步異步方法的情況下(例如,等待())或異步(例如,等待,ContinueWith)異步完成的方法。然而,在無效方法的情況下,沒有手柄被交還。異步void的方法也因此被稱爲「發射後不管」。

+0

問題具體詢問.ENET 4.0並解釋.NET 5? – Fulproof 2013-03-12 06:41:26