/// <summary> /// Get a table of hourly data per day from the cache or from the server /// </summary> /// <remarks>The returned table after loading is not changed by an instance of this class, /// thus, reading its data is thread safe. /// The method always returns a non-null object.</remarks> public SrezTableLight GetHourTable(DateTime date) { try { // getting the table of hourly slices from the cache date = date.Date; var utcNowDT = DateTime.UtcNow; var cacheItem = HourTableCache.GetOrCreateItem(date, utcNowDT); // block access to only one table of hourly slices lock (cacheItem) { var table = cacheItem.Value; // table to get var tableAge = cacheItem.ValueAge; // table file change time bool tableIsNotValid = utcNowDT - cacheItem.ValueRefrDT > DataValidSpan; // the table might be out of date // getting time slice table from server if (table == null || tableIsNotValid) { string tableName = SrezAdapter.BuildHourTableName(date); var newTableAge = serverComm.ReceiveFileAge(ServerComm.Dirs.Hour, tableName); if (newTableAge == DateTime.MinValue) { // the table file does not exist or there is no connection to the server table = null; // do not clog the log //log.WriteError($"Unable to receive modification time of the hourly data table {tableName}"); } else if (newTableAge != tableAge) // table file changed { table = new SrezTableLight(); if (serverComm.ReceiveSrezTable(tableName, table)) { table.FileModTime = newTableAge; table.LastFillTime = utcNowDT; } else { throw new ScadaException("Unable to receive hourly data table."); } } if (table == null) { table = new SrezTableLight(); } // update table in cache HourTableCache.UpdateItem(cacheItem, table, newTableAge, utcNowDT); } return(table); } } catch (Exception ex) { log.WriteException(ex, "Error getting hourly data table for {0} from the cache or from the server", date.ToLocalizedDateString()); return(new SrezTableLight()); } }
/// <summary> /// Получить таблицу часовых данных за сутки из кэша или от сервера /// </summary> /// <remarks>Возвращаемая таблица после загрузки не изменяется экземпляром данного класса, /// таким образом, чтение её данных является потокобезопасным. /// Метод всегда возвращает объект, не равный null</remarks> public SrezTableLight GetHourTable(DateTime date) { try { // получение таблицы часовых срезов из кэша date = date.Date; DateTime utcNowDT = DateTime.UtcNow; Cache <DateTime, SrezTableLight> .CacheItem cacheItem = HourTableCache.GetOrCreateItem(date, utcNowDT); // блокировка доступа только к одной таблице часовых срезов lock (cacheItem) { SrezTableLight table = cacheItem.Value; // таблица, которую необходимо получить DateTime tableAge = cacheItem.ValueAge; // время изменения файла таблицы bool tableIsNotValid = utcNowDT - cacheItem.ValueRefrDT > DataValidSpan; // таблица могла устареть // получение таблицы часовых срезов от сервера if (table == null || tableIsNotValid) { string tableName = SrezAdapter.BuildHourTableName(date); DateTime newTableAge = serverComm.ReceiveFileAge(ServerComm.Dirs.Hour, tableName); if (newTableAge == DateTime.MinValue) // файл таблицы не существует или нет связи с сервером { table = null; // не засорять лог /*log.WriteError(string.Format(Localization.UseRussian ? * "Не удалось принять время изменения таблицы часовых данных {0}" : * "Unable to receive modification time of the hourly data table {0}", tableName));*/ } else if (newTableAge != tableAge) // файл таблицы изменён { table = new SrezTableLight(); if (serverComm.ReceiveSrezTable(tableName, table)) { table.FileModTime = newTableAge; table.LastFillTime = utcNowDT; } else { throw new ScadaException(Localization.UseRussian ? "Не удалось принять таблицу часовых срезов." : "Unable to receive hourly data table."); } } if (table == null) { table = new SrezTableLight(); } // обновление таблицы в кэше HourTableCache.UpdateItem(cacheItem, table, newTableAge, utcNowDT); } return(table); } } catch (Exception ex) { log.WriteException(ex, Localization.UseRussian ? "Ошибка при получении таблицы часовых данных за {0} из кэша или от сервера" : "Error getting hourly data table for {0} from the cache or from the server", date.ToLocalizedDateString()); return(new SrezTableLight()); } }