C # Необходимо дождаться запуска события COM, прежде чем продолжить выполнение без контроля над событием.

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

Приложение, которое я делаю, является надстройкой стороннего производителя для Revit Structure. Они работают следующим образом: у меня есть библиотека классов с классом, который реализует интерфейс, когда это вызывается моим приложением.

Мой инструмент — это инструмент для печати, он предназначен для автоматизации печати в PDF. Я пытаюсь переместить свой код на использование PdfCreator для печати PDF-файлов (способ печати в Revit заключается в том, что вы устанавливаете принтер и вызываете метод «печати» в API, поэтому я не могу делать PDF-файлы каким-либо другим способом, кроме как через Принтер).

PDFCreator имеет отличный интерфейс COM, который позволяет вам устанавливать его настройки, а также подписываться на событие, которое срабатывает после печати каждого документа. Я вызываю метод hte print несколько раз, поэтому я хочу подождать, пока все не будет сделано, а затем сделать что-то в своем коде.

Моя логика выглядит следующим образом:

  1. Пользователь выбирает объекты для печати
  2. Нажимает кнопку «Печать» (в моем окне WPF)
  3. Затем My Code задает настройки создателя PDF и регистрируется для прослушивания события.
  4. Я вызываю метод API Print(), который затем занимает некоторое время для печати каждого из элементов.
  5. Затем я хочу быть предупрежден, когда все будет готово для печати, и выполнить некоторую «постобработку» документов.
  6. Постобработка включает в себя, среди прочего, переименование/перемещение PDF-файлов.

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

Что мне нужно сделать, так это дождаться события, не блокируя его.

Прочитав некоторые другие вопросы, я попробовал это:

  • AutoResetEvent и используйте функцию WaitOne, пока обработчик события не вызовет Set(). Это просто застряло на WaitOne и больше не продолжалось.
  • Application.DoEvents до тех пор, пока обработчик событий не установит определенную переменную класса.
  • Я пытался создать новую тему, чтобы подписаться на события, но это, похоже, не помогло.

как мне запустить событие в новом потоке, а затем предупредить текущий поток, чтобы он продолжал работать? Или как я могу заставить код ждать, пока событие сработает?

Дайте мне знать, если вам нужна дополнительная информация, с удовольствием предоставлю.


person RodH257    schedule 16.06.2010    source источник


Ответы (1)


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

Если вы используете какой-либо примитив ожидания в своем вызывающем коде, вы блокируете цикл сообщений, и поэтому событие никогда не запускается. Ваша программа не должна блокироваться — она должна продолжать выполнять цикл обработки сообщений, как это делает любая программа с графическим интерфейсом Windows.

person sharptooth    schedule 17.06.2010
comment
как мне продолжить цикл сообщений? нужно ли показывать форму и ждать события (у меня были некоторые проблемы с этим, но, возможно, я слишком рано сдался)? Моя программа вызывает метод API Print(), затем я хочу дождаться печати листов, а когда они будут готовы, сделать что-то еще. Показывать ли форму во время ожидания, а затем срабатывает событие? - person RodH257; 17.06.2010
comment
При попытке отобразить графический интерфейс с помощью ShowDialog я получаю исключение AccessViolationException в отношении чтения и записи защищенной памяти. - person RodH257; 17.06.2010
comment
Вы должны показать какое-то окно и просто сохранить его. Вы заметили, что если в окне есть кнопка и вы нажимаете эту кнопку, срабатывает обработчик события для этой кнопки? Это делается благодаря циклу сообщений, который запускается для вас. Вы также полагаетесь на него для обработчика событий COM. Вы просто сохраняете окно, запускается цикл сообщений, событие срабатывает и изменяет состояние вашего обработчика сообщений. - person sharptooth; 17.06.2010
comment
Я думаю, что стоит упомянуть (и, возможно, стоит обновить ответ), что это не относится к ключевому слову await. - person Matthijs Wessels; 19.11.2014