Как управлять отдельным приложением WPF? - PullRequest
0 голосов
/ 14 ноября 2018

Я разрабатываю дополнение Revit, которое выполняет некоторые длительные задачи. В ходе этого процесса я хочу отобразить простое окно WPF с неопределенным индикатором выполнения, меткой для информирования о текущем процессе и кнопкой для разрешения прерывания. Я уже попробовал наиболее очевидные способы сделать это: создать окно WPF внутри надстройки и отобразить его, но проблема в том, что пользовательский интерфейс зависает, независимо от того, как я это реализую. Во время некоторых процессов весь пользовательский интерфейс Revit замерзает / становится белым, поэтому я действительно не ожидал, что мое встроенное окно WPF в любом случае будет нормально работать в этих условиях.

Обходной путь, который я нашел, состоял в том, чтобы иметь окно WPF как отдельное приложение (файл EXE), которое я мог запустить из надстройки. Я основал свою реализацию на этом примере . Хорошая часть этого в том, что он не зависает независимо от того, что происходит с Revit. Плохо то, что последовательность того, как Windows ставит в очередь вызовы моего отдельного приложения WPF, иногда отличается от последовательности этих вызовов из моего дополнения. Иногда это приводит к ситуации, когда процесс Revit завершается, но окно WPF по-прежнему отображается (в ожидании последнего завершающего вызова, который, по-видимому, уже выполнен, но затем приложение возобновило работу с другим отложенным вызовом).

Желательно, чтобы я обрабатывал приложение WPF так же, как вы можете, например, обрабатывать приложение Excel из .NET. Вы создаете объект ExcelApp, делаете с ним все, что хотите, и в конце концов избавляетесь от него. Проблема в том, что я понятия не имею, как это сделать.

  • Как мне представить API приложения WPF для моей надстройки?
  • Может ли приложение WPF быть отзывчивым и управляемым из надстройки Revit одновременно? (пользователь все еще может нажать кнопку отмены, неопределенный индикатор выполнения не останавливается)

1 Ответ

0 голосов
/ 14 ноября 2018

Первое, что нужно знать о взаимодействии между двумя процессами. Есть несколько Стандартных подходов:

  • Взаимодействие через сокет (программирование сокетов)
  • Использование именованных конвейерных линий (полезно, когда ваши сообщения не такие длинные)

Есть несколько других предопределенных библиотек, основанных на вышеуказанных методах. Использование метода на основе файловой системы не является надежным способом подтверждения результатов.

Это было частью вашего решения. Следующим шагом будет использование Threading в вашем приложении WPF. Я не знаком с Revit и не знаю, как это работает. Замораживание пользовательского интерфейса является нормальным в длительном процессе. потому что пользовательский интерфейс занят и не может отвечать на ваши запросы (например, перемещение мыши, щелчок, ...). Таким образом, используя Thread , вы можете поместить свой длительный процесс в отдельное место и дождаться ответа в конце.

При использовании темы возникла проблема. Поскольку вы оставили свой пользовательский интерфейс и запустили длительный процесс в отдельном потоке, вы не можете напрямую получить доступ к своему ProgressBar. В этой ситуации вы должны использовать ThreadDispacher . Это не страшная концепция, это всего лишь три строки кодов, которые добавят к вашему призванию. например:

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

Найдите библиотеку для выполнения вашего IPC (межпроцессного взаимодействия), чтобы получить результат быстрее (или вы можете узнать о вышеупомянутых методах, чтобы сделать это своими средствами), а затем добавьте простой поток в ваше приложение WPF, чтобы вы могли иметь возможность запустить, приостановить и возобновить выполнение задания в зависимости от ситуации.

...