Очень странная ошибка при использовании System.Timers.Timer - PullRequest
1 голос
/ 27 октября 2008

По какой-то странной причине событие Elapsed запускается дважды, где оно определенно должно запускаться один раз. И сразу после этого таймер перестает работать ... Структура кода выглядит примерно так: Определенный объект определен для запуска определенного события, когда содержащееся в нем значение, которое постоянно обновляется с интервалами 500-1500 мс, увеличивается в сумме X по сравнению с предыдущим значением.

Например, если я определю свой X как 2, а значения, которые я получу, например, 1,2,1,2,3,4,8, событие сработает при вводе 8. Обработчик события для этого события запускает вышеупомянутый таймер, который работает в течение Y времени, прежде чем он истечет и вызовет проблемное событие. Если значение возвращается к нормальному значению до истечения таймера, таймер сбрасывается.

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

Общий результат в коде выглядит примерно так:

vMonitor.Range=X;
vMonitor.Over+= new EventHandler(StartTimer);
vMonitor.Normal+= new EventHandler(StopTimer);
vTimer.Elapsed+= new EventHandler(RaiseAlert);
source.BeginUpdate(vMonitor.Value);

Фактическая проблема заключается в том, что RaiseAlert срабатывает дважды по истечении таймера, а затем, как будто таймер перестает работать полностью, больше не срабатывает. Я думаю, что стоит упомянуть, что полное приложение содержит много потоковых операций, по крайней мере 2 потока работают одновременно, обновляя значения vMonitor.

Есть мысли?

Обновление:

Что касается потока, то довольно сложно объяснить точную структуру, но я могу сказать, что объект vMonitor содержится в другом объекте, который содержит значение обновления, которое постоянно изменяется различными потоками контролируемым образом. , конечно. Всякий раз, когда значение родительского объекта обновляется, оно сравнивается с vMonitor, и происходит соответствующее событие. Значение в vMonitor впоследствии заменяется значением родительских объектов.

РЕДАКТИРОВАТЬ: Я только что подтвердил это, делегат vTimer.Elapsed содержит только один правильный обработчик события.

Ответы [ 3 ]

3 голосов
/ 28 октября 2008

С MSDN :

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

0 голосов
/ 28 октября 2008

Отредактируйте, чтобы учесть то, что сказал Митч, потому что я полностью забыл, что это самый простой ответ. В методе, который обрабатывает событие Elapsed, убедитесь, что вы сначала останавливаете свой таймер, чтобы событие не сработало снова во время его обработки.

0 голосов
/ 27 октября 2008

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

Конечно, если есть несколько потоков, это совершенно другая игра с мячом!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...