【问题标题】:Async calls chaining in Metro appMetro 应用程序中的异步调用链
【发布时间】:2012-04-28 07:37:01
【问题描述】:

我是 Metro dev 的新手,我只希望我能够以一种可以理解的方式表达我的问题...

实际上,我正在将旧应用程序的一部分移植到 Metro。逻辑部分是一个单独的项目(便携式库),它应该用于 1)旧的 WPF 应用程序和 2)新的 Metro 应用程序。基本逻辑是相同的,但某些子系统(例如文件操作管理器)必须以不同方式编码 - 即 Metro 的异步方式。

我的问题是:我是否必须将调用者-被调用者的整个方法链重写为新的异步范式?假设我有 4 个方法链,从方法 A = Metro UI 事件异步处理程序开始(对我来说,将其编码为 async void 是有意义的,因为它是最重要的 fire&forget 事件),通过接下来的 2 个方法(B 和 C ) 放置在我的应用程序的不同层中,一直到包含“await CreateFileAsync”方法的方法 D(由 Microsoft 实现异步)。

现在:应该使用 await 调用异步 CreateFileAsync 方法。这迫使我也使方法 D 异步。要从 C 调用方法 D,从 B 调用 C,从 A 调用 B - 我是否必须将所有 A、B 和 C 重写为 async-await 样式?

我觉得我缺少更深层次的知识,所以我正在努力自学,但同时我想在这里碰碰运气......

我必须重写大部分代码吗?我上面的任何陈述有错吗?

提前非常感谢,汉斯

【问题讨论】:

    标签: c# user-interface asynchronous microsoft-metro async-await


    【解决方案1】:

    我建议您将可移植库重写为异步的。它不像以前那么糟糕了; Microsoft 在async/await 上非常努力,以尽可能轻松地将同步代码转换为异步代码。我预计在不久的将来会有很多其他人这样做,而 R# 可能会实现“make async”重写。

    在混合同步和异步代码时存在不明显的缺陷 - 请参阅 Stephen Toub 的上一篇博文 Should I expose synchronous wrappers for asynchronous methods? 出于这个原因,我认为将异步操作公开为异步 API(以及将同步操作公开为同步 API)更简洁。

    更新:如果您确实希望同步代码调用异步代码,那么您可以使用my AsyncEx library 中的Task.WaitAndUnwrapException 扩展方法。但是,您仍然有 Stephen Toub 的帖子中提到的问题,即:

    1. 如果您的库没有在所有可以使用的地方使用ConfigureAwait(false),您可能会出现死锁。
    2. 如果遇到线程池中的最大线程数,也可能会死锁。

    (2) 不再那么常见,但 (1) 是一种真正的可能性。刚刚测试async 的人经常使用brought up,因此他们将其与同步代码混合使用。

    【讨论】:

    • 嗨斯蒂芬,谢谢你的回答。几个小时前我读了那篇文章,但我会用新的眼光再读一次。问题是它有很多代码。最初我实现了 MVC 模式(当时不知道 MVVM),这给了我例如在控制器中相当多的一两线方法。我必须全部重写吗?如果我可以决定不...我将如何从我的同步 C 方法中调用我的异步 D 方法?
    • 如果我决定重写所有...在这一点上你同意那篇文章吗?
    • @Hans - 他写了那篇文章,所以我当然希望如此 :)
    • Stephen - Hans 链接到的那篇 2 月博客文章中的 Task.FromResult 让我感到困惑 - 如果你已经有了结果(当然),你只能使用它,那么为什么要使用这种方法呢?返回 Task 而不是 TResult?如果您确定您已经拥有预先计算的值(例如,来自内存缓存)并且需要保留 Task 作为“缓存未命中”情况的响应,我可以看到它,但这似乎并不是博客文章所指的 - 你能用一个示例方法详细说明吗?
    • @James:缓存就是一个很好的例子。其他时候,一个方法可以快速检查并返回一个常量,为复杂情况保存真正的async 实现(例如,fast path Database.MoveNextAsync example)。或者,如果它只是在一次调用另一个 async 方法之前进行一些(同步)预处理。或者,如果您从基类重写 Task<TResult> 方法,但具有同步实现。我会澄清博文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2015-12-19
    相关资源
    最近更新 更多