По какой-то странной причине событие 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 срабатывает дважды по истечении таймеров, а затем создается впечатление, что таймер полностью перестает работать, больше не срабатывает. Я думаю, стоит упомянуть, что полное приложение содержит много потоковой активности, по крайней мере, с двумя запущенными одновременно потоками, обновляющими значения vMonitor.
Какие-нибудь мысли?
Что касается потока, его довольно сложно объяснить точную структуру, но я могу сказать, что объект vMonitor содержится в другом объекте, который содержит значение обновления, которое постоянно изменяется различными потоками, конечно, контролируемым образом. . Каждый раз, когда значение родительского объекта обновляется, оно сравнивается с vMonitor, и запускается соответствующее событие. Значение в vMonitor впоследствии заменяется значением родительского объекта.
Обновлено: Я только что снова проверил, делегат vTimer.Elapsed содержит только один правильный обработчик событий.





Что ж, мой самый основной инстинкт состоял в том, что каким-то образом у вас действительно есть два подключения к событию Elapsed, что приводит к запуску двух событий. Я был пойман через это, иногда потому, что я добавил подключение событий вручную, когда оно уже было добавлено в конструкторе, или здесь есть некоторый аспект наследования, где подключение уже находится в базовом классе, и вы его повторяете в производном классе.
Конечно, если есть несколько потоков, это совсем другая игра!
Отредактируйте, чтобы учесть то, что сказал Митч, потому что я совершенно забыл, что это самый простой ответ. В методе, обрабатывающем событие Elapsed, убедитесь, что вы сначала останавливаете свой таймер, чтобы событие не сработало снова, пока оно обрабатывается.
От MSDN:
The Elapsed event is raised on a ThreadPool thread. If processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. Thus, the event handler should be reentrant.