using System; using System.Collections.Generic; using System.Text; using System.Timers; using System.Diagnostics; namespace WillemsWeerWachter { public class Worker { protected Timer workTimer; protected string name = "Worker"; protected int maxErrorsBeforeStopping = 4; protected int currentErrorCount = 0; protected int resetErrorCountAfterErrorFreeDays = 1; protected DateTime lastError; protected DateTime lastWorkCycleStarted; protected DateTime lastWorkCycleCompleted; public Worker(string name, int workTimerIntervalInSeconds) { this.name = name; this.workTimer = new Timer(workTimerIntervalInSeconds * 1000); this.workTimer.AutoReset = true; this.workTimer.Elapsed += new ElapsedEventHandler(workTimer_Elapsed); this.workTimer.Start(); } protected void workTimer_Elapsed(object sender, ElapsedEventArgs e) { managedWork(); } /* NOTE: * The ManagedWork function will run in a try/catch when the application is on production mode. * any error or crashes are catched and administors are mailed. * In debug mode however, all errors are 1-on-1 thrown to be able to * step into faulty code. */ public void managedWork() { workTimer.Stop(); lastWorkCycleStarted = DateTime.Now; // try { doActualWork(); lastWorkCycleCompleted = DateTime.Now; // } catch (Exception error) { currentErrorCount++; lastError = DateTime.Now; // } finally { // CHECK IF WORKER CAN CONTINUE OR MUST STOP NOW if (currentErrorCount < maxErrorsBeforeStopping) { // CAN CONTINUE: The current error count is within threshhold, go for another round: // Check if error rate can be resetted: if (lastError.AddDays(resetErrorCountAfterErrorFreeDays) < DateTime.Now) { // last error occurred long ago.., reset the counter currentErrorCount = 0; } // Start timer for another round if (!workTimer.Enabled) { workTimer.Start(); } } // } } protected virtual void doActualWork() { // do actual work here. } } }