2

我对 Metro 开发人员很陌生,我只希望我能够以一种可以理解的方式表达我的问题......

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

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

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

我能感觉到我缺少更深层次的知识,所以我正在努力教育自己,但同时我想在这里碰碰运气......

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

非常感谢,汉斯

4

1 回答 1

4

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

混合同步和异步代码时存在不明显的缺陷 - 请参阅 Stephen Toub 的上一篇博客文章我应该为异步方法公开同步包装器吗?出于这个原因,我认为将异步操作公开为异步 API(以及将同步操作公开为同步 API)更简洁。

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

  1. 如果您的库不能ConfigureAwait(false)在任何地方使用它,您可能会陷入僵局。
  2. 如果遇到线程池中的最大线程数,也可能会死锁。

(2) 不再那么常见,但 (1) 是一种真正的可能性。它经常由刚刚进行测试的人提出,因此async他们将其与同步代码混合在一起。

于 2012-04-16T23:52:30.530 回答