Является ли Application.DoEvents () моим единственным выбором (в данном случае)? - PullRequest
3 голосов
/ 01 октября 2010

У меня есть какое-то коммерческое оборудование, к которому я могу подключиться с помощью библиотеки .Net, поставляемой производителем оборудования, поэтому я не могу контролировать библиотеку или оборудование, только мой код.

Производитель настроил свою систему так, чтобы, если вы не подключены к оборудованию через их библиотеку, она работала нормально. Однако, когда вы соединяетесь с их библиотекой, существует неявное требование, чтобы вы обслуживали насос сообщений Windows со скоростью, установленной скоростью работы оборудования. Это потому, что в их библиотеке реализована система событий, на которую вы можете подписаться, чтобы отслеживать работу оборудования, но они предполагают, что код вашего приложения будет основан на WinForms. (Но в их документации нет ничего явно заявленного - только то, что все 2 из их примеров программ .Net основаны на WinForms.) Я подтвердил с их технической поддержкой, что вы ожидаете, что вы будете использовать приложение WinForms.

В моем случае я пишу приложение на C #, не основанное на WinForms (на самом деле это служба Windows, поэтому у меня нет потока пользовательского интерфейса), и хотя я подключаюсь к оборудованию, я не подписываюсь ни на одно из событий. , В результате я обнаружил, что мне нужно ссылаться на сборку WinForms и вызывать Application.DoEvents () с достаточно высокой скоростью, чтобы обслуживать все те события, на которые я не подписан.

Итак, мои вопросы таковы:

  1. В этом случае вызов Application.DoEvents () мой единственный вариант?
  2. Или есть более современный способ сделать это?
  3. Каковы последствия вызова DoEvents () при скорости 20 мс?
  4. Не имеет отношения, но если бы я написал приложение на основе WPF, вероятно, эта программа будет обслуживать насос сообщений?

Редактировать

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

Редактировать 2

Кроме того, поток, который я использую для взаимодействия с библиотекой, удален примерно на 2-3 поколения из исходного потока службы Windows.

Ответы [ 2 ]

6 голосов
/ 01 октября 2010

Это нормально, обычные предостережения для DoEvents здесь не применяются, потому что у вас нет пользовательского интерфейса.Разветвлений нет, скорость реалистичная.Application.Run () также прокачивает цикл сообщений, но вам будет труднее контролировать поток, так как вызов не возвращается.Да, WPF также перекачивает цикл сообщений, но его использование бесполезно, поскольку у вас нет пользовательского интерфейса.

Вы должны инициализировать поток службы, вызвав SetApartmentState () для выбора STA.Это гарантирует, что любой COM-сервер работает должным образом.

О, одно замечание, которое приходит на ум: вам нужно что-то сделать, чтобы поток не сгорел на 100% ядро.Это автоматически с Application.Run (), но не с DoEvents в «игровом цикле».Я думаю, что вы уже делаете, так как вы можете указать скорость 20 мсек.В противном случае вызов WaitHandle.WaitOne (20) для события запроса на остановку службы является типичным подходом.

2 голосов
/ 01 октября 2010

У вас может быть насос сообщений без форм, просто вызовите версию Application.Run(), которая принимает ApplicationContext или без параметров в потоке.

РЕДАКТИРОВАТЬ: Я бы порекомендовал версию ApplicaitonContext, чтобы вы могли вызывать ApplicationContext.ExitThread () в OnStop() вашего сервиса.

...