异步TaskCompletionSource调用方法两次

时间:2012-09-07 17:28:43

标签: c# async-await c#-5.0

found this way使用await通过回调调用异步方法,我在Argotic RSS阅读器库中使用它:

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;

这样很好用,我得到了我的物品。

我注意到Fiddler正在对RSS提要的网址进行两次调用。单步执行调试器中的代码后,会在LoadAsync上调用一次,在await tcs.Task上再调用一次。如何消除其中一个电话?

更新有一个可以downloaded from here显示此行为的控制台应用项目。

更新我已经改变了使用Argotic库的方式,因此我使用HttpClient下载RSS源,然后将内容作为字符串传递给Argotic只产生一个电话。如果有人有任何想法的话,我仍然想知道为什么它会被召唤两次。

1 个答案:

答案 0 :(得分:1)

看起来它是feed reader的异步API中的错误/功能。

它执行异步WebRequest以获取Feed。 但是,当它处理WebRequest完成时,它会为响应创建一个XmlReader,但实际上使用: SyndicationEncodingUtility.CreateSafeNavigator(Url, new WebRequestOptions(), null) 从源Url再次(同步)读取它。

Feed本身将在第二次缓存,因此不会造成大量开销。

认为可以通过将响应流传递给CreateSafeNavigator来修复它,但也许读取响应流也可以从异步完成中获益。