2014-02-11 3 views
0

«Простой» вопрос, в консольном приложении, как мы можем сделать System.Timers.Timer Истекшее событие вызывается в основном потоке?C# - System.Timers.Timer Истекшее событие в главной теме

Я прочитал кое-что о собственности SyncronizingObject, но в настоящее время у меня не было достаточного количества попыток реализовать класс, который реализует интерфейс ISyncronizeInvoke.

EDIT (для осветления):

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

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

Проблема в том, что устаревший код далек от потокобезопасности, и его адаптация будет довольно квестом.

Возможно, есть лучший подход.

+1

Зачем нужно выполнять на основной теме? Это просто, что вы хотите, чтобы основной поток ожидал, пока после того, как истекшее событие не сработало? – Sacrilege

+0

Какова ваша основная тема?WinFoems, WPF или, может быть, часть сервиса? –

+0

Это часть сервиса. – TiagoOliveira

ответ

3

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

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

while(!ShouldApplicationExit()) 
{ 
    var nextMesage = someQueueOfMessages.Dequeue(); 
    nextMessage(); 
} 

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

Вы можете сделать все это самостоятельно, если хотите. Если это не особенно важно, это не так много времени.

Другие варианты - использовать что-то еще для создания цикла сообщений, например Application.Run, который будет внутренне иметь цикл, который выглядит как-то вроде того, что я показал, под капотом.

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

+0

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

0

System.Timers.Timer может использоваться для инициирования событий, если вы счастливы, что событие поднято в потоке из пула системы.

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

См. .Net Timeouts: WaitForSingleObject vs Timer для аналогичного обсуждения.

Смежные вопросы