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; } }
private static IEnumerable <MemberInfo> GetSavableMembersFromTimedInterface(TimedInterface timedInterface) { BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; IEnumerable <MemberInfo> savableMembers = timedInterface .GetType() .GetMembers(bindingFlags) .Where(y => y.GetCustomAttribute <SavableAttribute>(true) != null); IEnumerable <MemberInfo> savableInterfaces = timedInterface .GetType() .GetInterfaces() .SelectMany(y => y.GetMembers(bindingFlags).Where(z => z.GetCustomAttribute <SavableAttribute>(true) != null)); foreach (MemberInfo savableAttribute in savableMembers) { yield return(savableAttribute); } foreach (MemberInfo savableAttribute in savableInterfaces) { yield return(savableAttribute); } }
public static void SaveConfiguration(TimedInterface timedInterface) { lock (SyncToken) { Type timedInterfaceType = timedInterface.GetType(); IEnumerable <MemberInfo> savableMembers = GetSavableMembersFromTimedInterface(timedInterface); if (!savableMembers.Any()) { return; } Dictionary <string, object> propertiesToSave = new Dictionary <string, object>(); foreach (MemberInfo member in savableMembers) { string memberKey = member.Name; object memberValue; switch (member) { case PropertyInfo pi: memberValue = pi.GetValue(timedInterface, null); break; case FieldInfo fi: memberValue = fi.GetValue(timedInterface); break; default: throw new NotSupportedException(); } propertiesToSave[memberKey] = memberValue; } string timedInterfaceSettingsData = JsonConvert.SerializeObject(propertiesToSave); File.WriteAllText(GetTimedInterfaceSettingsFilePath(timedInterface), timedInterfaceSettingsData); } }
private static string GetTimedInterfaceSettingsFilePath(TimedInterface timedInterface) { return(Path.Combine(SettingsDirectory, $"{timedInterface.GetType().Name}.json")); }
private async Task ExecuteInterface(TimedInterface timedInterface) { TimedInterfaceDbContext db = null; TimedInterfaceLog log = null; if (String.IsNullOrEmpty(MIF.Config.SqlConnectionString)) { return; } IScheduledInterface scheduledInterface = timedInterface as IScheduledInterface; try { timedInterface.Timer.LastStart = DateTime.Now; // Load the configuration data associated with the TimedInterface before each execution ConfigurationService.LoadConfiguration(timedInterface); // Every time this interface is executed, check if it's enabled. if (!timedInterface.IsEnabled) { return; } if (scheduledInterface != null && scheduledInterface.LastRunDateTime.HasValue) { DateTime now = DateTime.Now; if (now < scheduledInterface.NextRunDateTime) { return; } } // If there is a connection to a datbase, create a log detailing the Start / End date and times the interface ran if (!String.IsNullOrEmpty(MIF.Config.SqlConnectionString)) { lock (this.SyncToken) { db = new TimedInterfaceDbContext(); log = new TimedInterfaceLog { InterfaceName = timedInterface.GetType().Name, StartDateTime = DateTime.Now, ExecutablePath = Process.GetCurrentProcess().MainModule.FileName, MachineName = Environment.MachineName }; db.TimedInterfaceLogs.Add(log); } await db.SaveChangesAsync(); } DateTime lastRun = DateTime.Now; await timedInterface.Execute(); if (scheduledInterface != null) { scheduledInterface.LastRunDateTime = lastRun; } } finally { // Save the configuration data after each execution of the TimedInterface ConfigurationService.SaveConfiguration(timedInterface); if (db != null) { log.EndDateTime = DateTime.Now; await db.SaveChangesAsync(); await db.DisposeAsync(); } timedInterface.Timer.LastFinish = DateTime.Now; } }