【问题标题】:Async TaskCompletionSource calling method twiceAsync TaskCompletionSource 调用方法两次
【发布时间】:2013-08-16 20:17:40
【问题描述】:

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 提要的 url 进行了两次调用。在调试器中单步执行代码时,它会在LoadAsync 上调用一次,然后在await tcs.Task 上再次调用。我应该怎么做才能消除其中一个电话?

更新有一个控制台应用项目可以是downloaded from here,它演示了这种行为。

更新我更改了使用 Argotic 库的方式,因此我使用 HttpClient 下载 RSS 提要,然后将内容作为字符串传递给 Argotic,现在只生成一通电话。如果有人有任何想法,我仍然想知道为什么它被调用了两次。

【问题讨论】:

  • 如果你使用调试器,你会看到同样的效果吗?
  • 如果你根本不使用异步呢?例如,读者是否有可能简单地自然地进行两次调用(例如,一个 HEAD 然后一个 GET)?
  • 是的,同样的效果,它们都是 GET。我将恢复到同步版本并再次发表评论。
  • 嗯。我觉得这看起来没问题。你能把它放到一个简短但完整的控制台应用程序中,我回家后可以试试吗?看起来像是我喜欢深入挖掘的东西,一旦我复制了它......
  • 我怀疑 Argotic RSS 存在问题。如果不使用 TCS 使用 LoadAsync/Loaded,您会看到多少请求?

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


【解决方案1】:

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

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

feed 本身会被第二次缓存,所以不会造成很大的开销。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 2011-02-09
    • 2013-12-31
    相关资源
    最近更新 更多