Не всегда существует «лучший способ» для написания долговременного кода обработки событий. Это зависит от того, какое приложение вы разрабатываете.
Первый пример, который вы демонстрируете, - это идиоматический способ, которым вы часто будете видеть основной метод написанного долго работающего потока. Хотя обычно желательно использовать мьютекс или примитив синхронизации ожидаемых событий, а не вызов Sleep()
- в противном случае это типичный шаблон, используемый для реализации циклов обработки событий. Преимущество этого подхода заключается в том, что он позволяет специализированной обработке выполняться в отдельном потоке, позволяя основному потоку вашего приложения выполнять другие задачи или оставаться чувствительным к пользовательскому вводу. Недостатком этого подхода является то, что он может потребовать использования барьеров памяти (таких как блокировки), чтобы гарантировать, что общие ресурсы не будут повреждены. Это также затрудняет обновление вашего пользовательского интерфейса, так как вы обычно должны направлять такие вызовы обратно в поток пользовательского интерфейса.
Второй подход также часто используется - особенно в системах, в которых уже есть API для управления событиями, например WinForms, WPF или Silverlight. Использование объекта таймера или события Idle является типичным способом какие периодические проверки фона могут быть выполнены, если нет инициируемого пользователем события, которое запускает вашу обработку. Преимущество заключается в том, что легко взаимодействовать и обновлять объекты пользовательского интерфейса (так как они напрямую доступны из одного потока), и это уменьшает потребность в блокировках и мьютексах для защищенных данных. Одним из потенциальных недостатков этого подхода является то, что обработка, которая должна выполняться, отнимает много времени и может сделать ваше приложение не реагирующим на ввод данных пользователем.
Если вы не пишете приложения с пользовательским интерфейсом (например, службы), то первая форма используется гораздо чаще.
В качестве отступления ... когда это возможно, лучше использовать объект синхронизации, такой как EventWaitHandle или Семафор , чтобы сигнализировать, когда работа доступна для обработки. Это позволяет избежать использования объектов Thread.Sleep и / или Timer. Это уменьшает среднюю задержку между тем, когда работа доступна для выполнения, и когда запускается код обработки событий, и минимизирует накладные расходы на использование фоновых потоков, поскольку они могут быть более эффективно запланированы средой выполнения и не будут потреблять циклы ЦП. пока не будет работы.
Стоит также упомянуть, что если ваша обработка выполняется в ответ на обмен данными с внешними источниками (MessageQueues, HTTP, TCP и т. Д.), Вы можете использовать такие технологии, как WCF , чтобы обеспечить каркас обработки ваших событий. код. WCF предоставляет базовые классы, которые существенно упрощают реализацию как клиентских, так и серверных систем, которые асинхронно реагируют на активность событий связи.