c# - Why does Timer callback stop being invoked when an Exception is caught? -
i working on windows service runs following code:
public class servicecontroller { private fundsengine _fundsengine; protected override void onstart(string[] args) { var logspath = path.combine(appdomain.currentdomain.basedirectory, "logs"); if (directory.exists(logspath) == false) { directory.createdirectory(logspath); } _fundsengine = new fundsengine(); _fundsengine.start(); } } the service can start "engines" classes use timers execute code on specified interval.
the following class example of engine uses system.threading.timer invoke callback, ontick(), every 5 seconds.
public class fundsengine { private system.threading.timer _timer; private static logger _logger = logmanager.getcurrentclasslogger(); public void start() { _logger.trace("begin start"); try { // details omitted _timer = new timer(ontick); _timer.change(5000, timeout.infinite); } catch (exception exception) { _logger.errorexception("error in start.", exception); } { _logger.trace("end start"); } } private void ontick(object state) { _logger.trace("begin tick"); try { // stuff _timer.change(5000, timeout.infinite); } catch (exception exception) { _logger.errorexception("error in tick. ", exception); } { _logger.trace("end tick"); } } } as shown in log below, timer works expected, invoking ontick() method every 5 seconds.
2013-05-14 16:27:01.2261|trace|begin start 2013-05-14 16:27:03.8514|trace|end start 2013-05-14 16:27:08.8569|trace|begin tick 2013-05-14 16:27:08.8709|trace|end tick 2013-05-14 16:27:13.8734|trace|begin tick 2013-05-14 16:27:13.8734|trace|end tick 2013-05-14 16:27:18.8809|trace|begin tick 2013-05-14 16:27:18.8809|trace|end tick 2013-05-14 16:27:23.8894|trace|begin tick 2013-05-14 16:27:23.8894|trace|end tick 2013-05-14 16:27:28.8969|trace|begin tick 2013-05-14 16:27:28.8969|trace|end tick 2013-05-14 16:27:33.9044|trace|begin tick 2013-05-14 16:27:33.9044|trace|end tick in event exception caught in ontick() method, expectation logged, , service continue running, such ontick() method invoked again in 5 seconds. however, not case, callback never invoked again after exception handled. why this?
2013-05-14 16:29:03.8574|trace|begin start 2013-05-14 16:29:03.8574|trace|end start 2013-05-14 16:29:08.8709|trace|begin tick 2013-05-14 16:29:09.9750|error|error in tick. system.net.sockets.socketexception (0x80004005): no connection made because target machine actively refused 127.0.0.1:22 2013-05-14 16:29:09.9750|trace|end tick
_timer.change(5000, timeout.infinite); you didn't create period timer, passing infinite period argument. timer call ontick() once. code incomplete, way work when calls change() again recharge timer.
so high odds change() call getting bypassed exception. if want keep going change() call belongs in finally block. although not idea this, non-zero odds process state corrupted , crash again. on , over. should @ least take countermeasure against , count number of consecutive crashes, giving when bombs repeatedly.
Comments
Post a Comment