Избегание межпроцессных вызовов при автоматизации Word с помощью VB.net

StackOverflow https://stackoverflow.com/questions/3868015

Вопрос

Сокращенная версия У меня есть надстройка Word в VB.net и VSTO, которая предоставляет COM-совместимый объект через Word.COMAddins.Объект, так что функциональность добавления может быть вызвана внешней по отношению к Word, без того, чтобы доступ к самому Word был межпроцессным.

Этот метод работал в VB6, но с VB.net он все еще работает, но намного медленнее, чем тот же код, запускаемый непосредственно из надстройки через панель задач, как будто все вызовы являются межпроцессорными, хотя их не должно быть.x

Длинная версия Это дополнение, по сути, выполняет тонну обработки документов Word.Надстройку можно запустить двумя способами.

  1. из Word, используя панель задач
  2. внешне, через набор классов , доступных для COM (потому что я должен предоставлять доступ к функциональности клиентским приложениям VB6.

НО вот в чем загвоздка.Любой, кто когда-либо занимался автоматизацией Word, знает, что код, который работает совершенно приемлемо INPROC с Word (в данном случае экземпляр надстройки, который загружает сам Word), как правило, будет выполняться неприемлемо медленно вне процесса (или между процессами).

Это приложение ничем не отличается.

Давным-давно я воспользовался удобным приемом, чтобы обойти эту проблему.

  1. Создайте Добавление слова как обычно
  2. Предоставьте доступ к объекту с помощью свойства Word.COMAddin.Object, которое позволит внешнему коду получить доступ к вашему надстройке.
  3. Во внешнем проекте вместо того, чтобы напрямую манипулировать Word, используйте Приложение.Коллекция COMAddins, найдите свой аддин, извлеките открытый COMAddin.Свойство объекта из него, а затем вызовите метод для этого объекта, который выполняет работу.

Конечно, звонок вашему комаддину.Object объект по-прежнему будет межпроцессным, но, как только выполнение будет выполнено в надстройке, которая ОБРАБАТЫВАЕТСЯ с помощью Word, ваш addin теперь может выполнять все манипуляции с объектом Word, которые он хочет, и это быстро, потому что на этом этапе все они являются вызовами в процессе.

Это работало во времена VB6 COM.

Но, я собрал в этом VB.net надстройки VSTO addin, а подставлять свою надстройки объекта с помощью функции RequestComAddInAutomationService объекта ВСТО подключения

Я могу выполнять вызовы в свой addin извне, и все они работают точно так, как я бы ожидал от них, за исключением того, что все они + медленные +, очень похоже на то, что вызовы в Word все еще выполняются между процессами, хотя код, выполняющий эти вызовы Word, является частью библиотеки dll addin, которая была загружена Word в процессе!

И медленно, примерно в соотношении 10 к 1;то, что занимает 3 секунды для запуска непосредственно из надстройки через панель задач, занимает ~ 30 секунд для запуска при вызове из внешнего кода через объект COMADDIN.object.

Я предполагаю, что я столкнулся с какой-то проблемой с ДОМЕНАМИ приложений .net или чем-то в этом роде, и что на самом деле представляет собой перекрестные вызовы proc в .net, но пока я не нашел ничего, что могло бы даже намекнуть на подобные вещи.

Моим следующим шагом, если не считать некоторого мистического озарения, будет создание кода воспроизведения, что может оказаться сложным из-за большого количества элементов в игре.

Есть какие-нибудь мысли?

Это было полезно?

Решение 2

К сожалению, техника захвата событий, о которой упоминает Торбен, не сработала бы в моей конкретной ситуации.

Итак, я закрываю этот вопрос обходным путем, который я упомянул в комментариях, и я повторю здесь...

Ну, не идеальное решение, но я нашел +a+ решение.Это включало таймер, так что это определенно неоптимально По сути, когда надстройка загружается Word (т. Е. во время события ЗАПУСКА), инициализируйте таймер (таймер WINFORMS, а не таймер обработки потоков) и установите его интервал равным 500.Когда внешний код подключается к надстройке через COMADDIN.Свойство OBject и выполняет вызов надстройки, устанавливающей флаг переменной, которая опрашивается таймером.Когда таймер видит, что он установлен, он сбрасывает флаг и выполняет действие.

Это не самое чистое решение, которое я бы предпочел, но оно довольно простое в реализации, умеренно понятное постфактум, и оно определенно позволяет избежать замедления COM-вызовов xprocess в Word.

Другие советы

Я сделал те же наблюдения с моей надстройкой VSTO Word.Что я хотел бы здесь добавить:Когда вы добавляете свою процедуру в качестве обработчика щелчков к кнопке:

`this.testButton.Click += новый офис._CommandBarButtonEvents_ClickEventHandler(ваша процедура);

и реализуйте свою дорогостоящую процедуру в "YourProcedure", вы можете вызвать поток пользовательского интерфейса Word, используя

this.testButton.Выполнить();

Это тоже не элегантное решение, но, возможно, полезное, если у вас есть готовые кнопки на командной панели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top