2012-09-07 46 views
4

有使用await調用一個回調異步方法的found this way,我用它在Argotic RSS閱讀器庫:異步調用TaskCompletionSource方法兩次

var tcs = new TaskCompletionSource<string>(); 

EventHandler<SyndicationResourceLoadedEventArgs> feedReaderOnLoaded = null; 
feedReaderOnLoaded = (sender, args) => 
       { 
        feedReader.Loaded -= feedReaderOnLoaded; 
        tcs.SetResult(""); // Needed so the await completes 
       }; 
feedReader.Loaded += feedReaderOnLoaded; 
feedReader.LoadAsync(new Uri(feed.Url), new object()); 

await tcs.Task; 

// Result is put in a property, rather than returned from the method 
var items = feedReader.Channel.Items; 

所以這工作得很好,我得到我的項目。

我注意到小提琴手兩個呼叫正在對RSS提要的網址發出。在調試器中單步執行代碼時,將在LoadAsync上調用一次,並在await tcs.Task上再次調用該代碼。我應該做些什麼來消除其中一個呼叫?

UPDATE有一個控制檯應用程序項目,可以是downloaded from here,演示此行爲。

UPDATE我已經改變了我如何使用Argotic庫,所以,我下載使用HttpClient RSS提要,然後通過內容Argotic作爲一個字符串,它現在只產生一個呼叫。如果有人有任何想法,我仍然想知道爲什麼它被稱爲兩次。

+0

你看到同樣的效果,如果你*不*使用調試器呢? –

+2

如果你根本不使用異步?例如,讀者是否有可能自然而然地做出兩個調用(例如,HEAD然後是GET)? –

+0

是的,效果相同,它們都是GET。我會再次回到同步版本並發表評論。 – harriyott

回答

1

看起來它是異步API的feed reader中的錯誤/功能。

它執行一個異步的WebRequest獲得飼料。 但是,當它處理WebRequest完成時,它會爲響應創建一個XmlReader,但實際上使用: SyndicationEncodingUtility.CreateSafeNavigator(Url, new WebRequestOptions(), null) 它從源URL再次(同步)讀取它。

飼料本身將被緩存的第二次,所以它不會導致大規模的開銷。

認爲它可以通過響應流傳遞給CreateSafeNavigator但也許讀取響應流可以從異步以及正在做有利於固定。