C#中异步调用的设计模式

Ily*_*gan 5 c# mvp asynchronous domain-driven-design

我正在设计一个具有多个层的桌面应用程序:GUI层(WinForms MVP)保存对适配器类接口的引用,这些适配器调用执行实际工作的BL类.

除了执行来自GUI的请求之外,BL还会触发GUI可以通过接口订阅的一些事件.例如,CurrentTimeBL中的一个对象会定期更改,GUI应该反映更改.

有两个涉及多线程的问题:

  1. 我需要使一些逻辑调用异步,以便它们不会阻止GUI.
  2. GUI接收的一些事件是从非GUI线程触发的.

处理多线程的最佳级别是什么?我的直觉说Presenter是最适合的,我是对的吗?你能给我一些做我需要的示例应用程序吗?并且主持人是否有理由持有对表单的引用,以便它可以调用它上面的代理?

编辑:赏金可能会去亨利克,除非有人给出更好的答案.

Ste*_*ary 5

我会考虑使用Task基于BLL的BLL来表示那些可以被描述为"后台操作"的部分(也就是说,它们是由UI启动并具有明确的完成点).在Visual Studio中异步CTP包括描述基于任务的异步模式(TAP)的文件; 我建议以这种方式设计BLL API(即使尚未发布async/ awaitlanguage扩展).

对于BLL的"订阅"部分(即,它们由UI启动并无限期地继续),有几个选项(按照我个人喜好的顺序):

  1. 使用Task基于API但具有TaskCompletionSource永不完成的API (或仅在应用程序关闭时被取消而完成).在这种情况下,我建议写你自己的IProgress<T>EventProgress<T>(在异步CTP):该IProgress<T>给你的BLL对报告进展情况(更换进度事件)的接口和EventProgress<T>处理捕获SynchronizationContext的编组"报告进度"授人以UI线程.
  2. 使用Rx的IObservable框架; 这是一个很好的设计搭配,但学习曲线相当陡峭,并且比我个人喜欢的稳定性差(它是一个预发布库).
  3. 使用老式的基于事件的异步模式(EAP),您可以SynchronizationContext在其中捕获BLL并通过将事件排队到该上下文来引发事件.

编辑2011-05-17:自编写上述内容以来,Async CTP团队已经表示不建议使用方法(1)(因为它有点滥用"进度报告"系统),并且Rx团队发布了明确其语义的文档.我现在推荐Rx用于订阅.