如何控制单独的WPF应用程序?

时间:2018-11-14 11:10:06

标签: c# wpf api-design

我正在开发执行一些冗长任务的Revit插件。在此过程中,我想显示一个带有不确定进度条的简单WPF窗口,一个用于通知当前过程的标签以及一个用于中止操作的按钮。 我已经尝试了最明显的方法来实现:在附加组件内创建WPF窗口并显示它,但是问题是无论我如何实现,UI都被冻结。在某些过程中,整个Revit UI会冻结/变白,因此我真的不希望我的嵌入式WPF窗口在这些情况下仍能正常工作。

我发现的解决方法是将WPF窗口作为一个单独的应用程序(EXE文件),可以从加载项运行该窗口。我的实现基于this example。 好处是无论Revit发生什么情况,它都不会挂起。 糟糕的是,Windows如何对我单独的WPF应用程序的调用进行排队的顺序有时与我的加载项中的这些调用顺序不同。有时会导致Revit进程结束但仍显示WPF窗口的情况(等待显然已经执行的最终关闭调用,但随后又有另一个延迟的调用重新激活了应用程序)。

最好,我想以与您可以使用的相同方式来处理WPF应用程序,即,从.NET处理Excel应用程序。您创建一个ExcelApp对象,对其进行所需的处理,最后进行处理。 问题是我不知道如何执行此操作。

  • 如何将WPF应用程序的API公开给我的附加组件?
  • 是否可以同时从Revit加载项使WPF应用程序响应和控制? (用户仍然可以单击中止按钮,不确定的进度条不会冻结)

1 个答案:

答案 0 :(得分:0)

首先要了解的是两个流程之间的交互。有一些标准方法:

  • 通过套接字进行交互(套接字编程)
  • 使用命名管道(在消息不太长时间时很有用)

还有一些其他基于上述技术的预定义库。使用基于文件系统的方法不是验证输出的可靠方法。

这是您解决方案的一部分。下一步是在WPF应用程序中使用 Threading 。我对Revit并不熟悉,也不知道它是如何工作的。 在长时间运行的过程中,UI冻结是正常的。因为UI很忙,无法回答您的请求(例如,鼠标移动,单击等)。因此,使用 Thread ,您可以将长时间运行的进程放在单独的位置,然后等待响应结束。

使用线程时出现问题。因为您离开了UI并在单独的线程上开始了长期运行的进程,所以您无法直接访问ProgressBar。在这种情况下,您必须使用 ThreadDispacher 。这不是一个可怕的概念,它只是三行代码,将增加您的调用。 例如:

    Dispatcher.Invoke(() =>
        {
            ProgressBar.Value++;
        });

搜索一个库以进行IPC(进程间通信)以更快地获得结果(或者您可以通过自己的方法来学习上述技术),然后在WPF应用程序中添加一个简单的线程,这样您就可以根据情况启动,暂停和继续运行的作业。