private async void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { TimedInterfaceServiceTimer serviceTimer = sender as TimedInterfaceServiceTimer; serviceTimer.Stop(); try { await this.HandleRunAfterAttributeForTimedInterface(serviceTimer.TimedInterface); await this.ExecuteInterface(serviceTimer.TimedInterface); if (serviceTimer.Interval != serviceTimer.TimedInterface.Interval.TotalMilliseconds) { serviceTimer.Interval = serviceTimer.TimedInterface.Interval.TotalMilliseconds; } } catch (Exception ex) { await ex.LogException(serviceTimer.TimedInterface.GetType().Name); serviceTimer.Interval = TimeSpan.FromHours(6).TotalMilliseconds; } finally { serviceTimer.Start(); } }
private async void StartTimer(TimedInterfaceServiceTimer timer) { #if DEBUG await this.HandleRunAfterAttributeForTimedInterface(timer.TimedInterface); // Execute the interface initially, otherwise will have to wait for the first timer to elapse before anything happens. await this.ExecuteInterface(timer.TimedInterface); #endif timer.Start(); }
private void StartInterfaces() { // Create a timer for each interface foreach (TimedInterface timedInterface in this.TimedInterfaces) { TimedInterfaceServiceTimer timer = new TimedInterfaceServiceTimer(timedInterface); timer.Elapsed += this.Timer_Elapsed; timedInterface.Timer = timer; } foreach (TimedInterface timedInterface in this.TimedInterfaces) { this.StartTimer(timedInterface.Timer); } }
private async Task HandleRunAfterAttributeForTimedInterface(TimedInterface timedInterface) { RunAfterAttribute runAfterAttribute = timedInterface.GetType().GetCustomAttribute <RunAfterAttribute>(); if (runAfterAttribute == null) { return; } TimedInterface interfaceToRunAfter = this.TimedInterfaces.FirstOrDefault(y => y.GetType() == runAfterAttribute.InterfaceTypeToRunAfter); if (interfaceToRunAfter == null) { throw new Exception($"{timedInterface.GetType().Name} cannot run after {runAfterAttribute.InterfaceTypeToRunAfter.Name} as it can't be found"); } TimedInterfaceServiceTimer interfaceToRunAfterTimer = interfaceToRunAfter.Timer; // If the interface to run after hasn't completed a first run, or it has started again but hasn't finished if (!interfaceToRunAfterTimer.LastFinish.HasValue || interfaceToRunAfterTimer.LastStart > interfaceToRunAfterTimer.LastFinish) { TaskCompletionSource <bool> waitForFinishTaskCompletionSource = new TaskCompletionSource <bool>(); interfaceToRunAfterTimer.PropertyChanged += InterfaceToRunAfterTimer_PropertyChanged; void InterfaceToRunAfterTimer_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { // When the LastFinish property is updated, set the CompletionSource result so program flow may continue; if (e.PropertyName == nameof(interfaceToRunAfterTimer.LastFinish)) { interfaceToRunAfterTimer.PropertyChanged -= InterfaceToRunAfterTimer_PropertyChanged; waitForFinishTaskCompletionSource.SetResult(true); } } // Block the flow of the function until the LastFinish property has been updated await waitForFinishTaskCompletionSource.Task; } }