2012-01-24 11 views
5

在.NET 4中使用TPL,我試圖決定如何設計處理未來的API。這發生在我是模仿異步模式,但沒有End(IAsyncResult)方法一種可能性:這個TPL習語存在嗎?

public Task<int> BeginGetAge() 
{ 
    // create and return task 
} 

public int GetAge() 
{ 
    return this.BeginGetAge().Result; 
} 

因此,主叫方可以決定是否調用阻塞或非阻塞的GetAge()版本。而且,他們可以訪問未來,因此可以在它之上構建延續等等。

這個習語有效嗎?我有什麼明顯的缺點或問題,我錯過了?它可能甚至有一個正式的名字?

+0

我相信你的第二種情況會從'await'中大大受益。 – user7116

+0

僅供參考,Stephen Toub發佈了關於此內容(爲異步方法提供同步包裝) - tl; dr避免它:)請參閱http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638。 aspx和http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx –

回答

3

返回Task是新的C#5異步方式 - 它被稱爲TAP:Task-based Asynchronous Pattern

唯一的區別是該方法被命名爲GetAgeAsync

所以,是的 - 建議使用這種方法,因爲它可以輕鬆移植到C#5異步時發佈。

+0

非常有幫助的參考 - 謝謝。 –

2

這個習慣用法對我來說似乎是完全有效的,確實支持基於異步的Task將成爲即將發佈的.Net版本的一大特性。

但是,我會改變你的實現,所以阻止方法GetAge不會調用異步方法,然後等待它 - 在(可能)創建一個新線程的開銷是不必要的。

+0

可以調換方法之間的關係,並讓'BeginGetAge()'返回任務 .Factory.StartNew(()=> GetAge())'。 –

+0

@SeanU準確地說。 –

+1

嗯,我不認爲它會創建一個新的線程,以至於切換到現有線程的上下文。即使如此,由調度人員決定是否有必要。但我明白你的意思,肖恩的建議是有道理的。 –