/// <summary> /// Загрузить представление от сервера /// </summary> protected bool LoadView(Type viewType, int viewID, DateTime viewAge, ref BaseView view, out DateTime newViewAge) { UiObjProps viewProps = GetViewProps(viewID); newViewAge = serverComm.ReceiveFileAge(ServerComm.Dirs.Itf, viewProps.Path); if (newViewAge == DateTime.MinValue) { throw new ScadaException(Localization.UseRussian ? "Не удалось принять время изменения файла представления." : "Unable to receive view file modification time."); } else if (newViewAge != viewAge) // файл представления изменён { // создание и загрузка нового представления if (view == null) { view = (BaseView)Activator.CreateInstance(viewType); } view.SetArgs(viewProps.Args); if (serverComm.ReceiveView(viewProps.Path, view)) { view.UpdateTitle(viewProps.ShortTitle); return(true); } else { throw new ScadaException(Localization.UseRussian ? "Не удалось принять представление." : "Unable to receive view."); } } else { return(false); } }
/// <summary> /// Получить представление из кэша или от сервера /// </summary> /// <remarks>Метод используется, если тип предсталения неизвестен на момент компиляции</remarks> public BaseView GetView(Type viewType, int viewID, bool throwOnError = false) { try { if (viewType == null) { throw new ArgumentNullException("viewType"); } // получение представления из кэша DateTime utcNowDT = DateTime.UtcNow; Cache <int, BaseView> .CacheItem cacheItem = Cache.GetOrCreateItem(viewID, utcNowDT); // блокировка доступа только к одному представлению lock (cacheItem) { BaseView view = null; // представление, которое необходимо получить BaseView viewFromCache = cacheItem.Value; // представление из кэша DateTime viewAge = cacheItem.ValueAge; // время изменения файла представления DateTime newViewAge; // новое время изменения файла представления if (viewFromCache == null) { // создание нового представления view = (BaseView)Activator.CreateInstance(viewType); if (view.StoredOnServer) { if (LoadView(viewType, viewID, viewAge, ref view, out newViewAge)) { Cache.UpdateItem(cacheItem, view, newViewAge, utcNowDT); } } else { UiObjProps viewProps = GetViewProps(viewID); view.Path = viewProps.Path; view.SetArgs(viewProps.Args); view.UpdateTitle(viewProps.ShortTitle); Cache.UpdateItem(cacheItem, view, DateTime.Now, utcNowDT); } } else if (viewFromCache.StoredOnServer) { // представление могло устареть bool viewIsNotValid = utcNowDT - cacheItem.ValueRefrDT > ViewValidSpan; if (viewIsNotValid && LoadView(viewType, viewID, viewAge, ref view, out newViewAge)) { Cache.UpdateItem(cacheItem, view, newViewAge, utcNowDT); } } // использование представления из кэша if (view == null && viewFromCache != null) { if (viewFromCache.GetType().Equals(viewType)) { view = viewFromCache; } else { throw new ScadaException(Localization.UseRussian ? "Несоответствие типа представления." : "View type mismatch."); } } // привязка свойств каналов или обновление существующей привязки if (view != null) { dataAccess.BindCnlProps(view); } return(view); } } catch (Exception ex) { string errMsg = string.Format(Localization.UseRussian ? "Ошибка при получении представления с ид.={0} из кэша или от сервера: {1}" : "Error getting view with ID={0} from the cache or from the server: {1}", viewID, ex.Message); log.WriteException(ex, errMsg); if (throwOnError) { throw new ScadaException(errMsg); } else { return(null); } } }