【发布时间】:2014-02-27 04:19:37
【问题描述】:
我有一个 WPF 程序,我的模型需要加载 "Out-of-Proc" (.exe) COM 组件,以便在用户在 UI 上执行操作时实现一些验证.我想通知用户,将进行长时间的操作,让他知道应用程序很忙,而不仅仅是冻结。但是 UI 上的任何操作都会在 COM 操作完成后发生。
我认为任何 COM 通信都应该在主 UI 线程上完成。它消除了在主 (UI) 线程之外的另一个线程上运行的任何解决方案。
我尝试了很多选项都没有成功:
- MSDN Dispatcher.PushFrame (DoEvents)
- StackOverflow HCL (PushFrame)
- Jason programming Blog (PushFrame)
我无法从需要刷新 UI 的模型中实现同步操作。 我的操作有一个属性“IsLoading”,我从我的视图中订阅了该属性,并且我尝试根据其状态更新 UI,但似乎在 WPF 中这是不可能的???
还有其他建议吗?
我可以使用 async/await 并从另一个运行另一个调度程序的线程执行我的 COM 操作(有点复杂),并且会失去所需的同步性(用户需要 COM 操作的结果才能继续其工作)?
主要针对盲人... 一些更清晰的解释(有关所需同步性的更多详细信息):
当用户单击 TreeView 项目时,我会加载一个网格,然后需要验证在网格中输入的数据是否仍然有效。要进行验证,我需要通过 COM 加载应用程序并自动加载文档,然后解析它并验证网格中的数据(在视图中的网格模型中)。这需要 10 秒。 如果我在另一个线程上执行此操作,那么用户可以执行一个操作来选择在网格中添加一个新行,该行仍然依赖于与前一个文档一起加载的同一个 COM 应用程序。我仍然需要等待应用程序加载。这是一个同步动作。我的应用程序依赖于该 COM 应用程序,其加载的文档处于有效状态,以便用户采取更多操作。但是我需要给用户一些关于我正在做什么的反馈(启动 COM 应用程序并加载文档)。在另一个线程上执行 COM 操作只是稍后报告问题,但不能解决用户需要等待操作完成的事实。我认为我需要(强制)更新我的 WPF 应用程序,但找不到任何(扭曲的)方法。
【问题讨论】:
-
出于好奇,为什么要从主 UI 线程调用 COM?
-
你认为为什么需要在 UI 线程中完成?
-
据我所知,几乎所有 COM 组件都是 STA(单线程单元),应该从应用程序的第一个线程 (UI) 调用...因为 CoInitialize() 我认为?
-
当使用托管线程中的 COM 对象时,CLR 将自动创建一个单线程单元并编组来自该单元的所有调用/返回。 See here for source。如果您使用的是 STA COM 对象,请确保将后台线程标记为 STA。
-
@Lukazoid,如果我理解正确,我可以将一个工作线程标记为 STA,然后在该线程上创建一个 COM 对象。但是该对象是可以直接从我的主线程访问,还是我必须通过之后创建它的线程。 (另外,有没有办法将它与我的主线程同步?...否则可能会发生预期 COM 操作完成但未完成的操作)?
标签: c# wpf multithreading com doevents