using Newtonsoft.Json; using NLog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IOB_MAN.Core { /// /// Classe TaskRunStats gestisce le statistiche di esecuzione dei task. /// Memorizza e calcola i tempi medi, il numero di esecuzioni e le dimensioni dei dati. /// Supporta il salvataggio delle statistiche su disco e il caricamento da file esistenti. /// public class TaskRunStats { #region Public Constructors /// /// Inizializza una nuova istanza della classe con dati vuoti. /// Utilizzato quando non è necessario caricare dati da file. /// public TaskRunStats() { // Inizializzazione generica senza rilettura dei dati dal disco } /// /// Inizializza una nuova istanza della classe con rilettura dei dati dal disco. /// Carica eventuali statistiche memorizzate in un file di configurazione. /// /// Directory dell'applicazione dove si trova il file di configurazione. /// Nome del file di configurazione da cui caricare i dati. public TaskRunStats(string appDir, string confName) { AppDir = appDir; ConfName = confName; // Inizia il caricamento dei dati dal disco (se presenti) tryReload(); } #endregion Public Constructors #region Public Properties /// /// Tempo medio complessivo registrato per tutti i task. /// Calcolato sommando i tempi medi di ogni singolo task. /// public TimeSpan AvgTotalTime { get { TimeSpan answ = new TimeSpan(); if (TaskData != null && TaskData.Count > 0) { foreach (var record in TaskData) { answ += record.Value.AvgTime; } } return answ; } } /// /// Numero totale di statistiche memorizzate per i task. /// Rappresenta il conteggio dei record presenti nel dizionario. /// public int NumItems { get { return TaskData.Count; } } /// /// Dimensione massima delle statistiche memorizzate per un task. /// Indica il numero massimo di esecuzioni registrate per un singolo task. /// public long SampleSizeMax { get { return TaskData.Max(x => x.Value.NumRun); } } /// /// Dizionario che contiene le statistiche per ogni task registrato. /// Ogni chiave rappresenta il nome del task, ogni valore contiene le informazioni di esecuzione. /// public Dictionary TaskData { get; set; } = new Dictionary(); #endregion Public Properties #region Public Methods /// /// Calcola il tempo medio per un task specifico. /// /// Nome del task per cui si desidera calcolare il tempo medio. /// Tempo medio per il task specificato. public TimeSpan AvgTaskTime(string taskName) { TimeSpan answ = new TimeSpan(); if (TaskData != null && TaskData.Count > 0) { if (TaskData.ContainsKey(taskName)) { answ = TaskData[taskName].AvgTime; } } return answ; } /// /// Resetta tutte le statistiche e le azzera. /// public void ForceReset() { TaskData = new Dictionary(); } /// /// Registra i dati di un'operazione di esecuzione per un task specifico. /// Aggiorna i dati esistenti o crea un nuovo record se il task non è già presente. /// /// Nome del task che viene eseguito. /// Durata dell'esecuzione in unità di tempo. public void RecordExeData(string taskName, TimeSpan duration) { // Cerca nel dizionario se il task è già presente if (TaskData.ContainsKey(taskName)) { TaskData[taskName].NumRun++; TaskData[taskName].TotalTime += duration; } else { TaskData.Add(taskName, new TaskStat() { NumRun = 1, TotalTime = duration }); } } /// /// Salva le statistiche memorizzate sul disco in un file JSON. /// public void SaveToDisk() { var rawData = JsonConvert.SerializeObject(TaskData, Formatting.Indented); if (rawData != null && rawData.Length > 2) { File.WriteAllText(StatsPath, rawData); } } #endregion Public Methods #region Private Fields /// /// Oggetto logger per il rilevamento degli eventi e degli errori. /// private static Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields #region Private Properties /// /// Directory dell'applicazione dove si trova il file di configurazione. /// private string AppDir { get; set; } = ""; /// /// Nome del file di configurazione da cui caricare i dati. /// private string ConfName { get; set; } = ""; /// /// Percorso del file di statistiche su disco. /// Generato dinamicamente con Path.Combine(AppDir, ConfName). /// private string StatsPath { get => Path.Combine(AppDir, ConfName); } #endregion Private Properties #region Private Methods /// /// Tenta il caricamento dei dati dal file di configurazione. /// Se il file esiste, lo legge e lo deserializza in un dizionario. /// Gestisce eventuali eccezioni di deserializzazione. /// private void tryReload() { if (File.Exists(StatsPath)) { string rawData = File.ReadAllText(StatsPath); if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) { try { TaskData = JsonConvert.DeserializeObject>(rawData) ?? new Dictionary(); } catch (Exception exc) { Log.Error($"Eccezione in tryReload:{Environment.NewLine}{exc}"); } } } } #endregion Private Methods } }