/// <summary> /// Установить содержание для запроса /// </summary> protected override void setQuery() { int idReq = HMath.GetRandomNumber() , i = -1; string cmd = string.Empty; //перевод даты для суточного набора if (DateTimeStart != DateTimeBegin) { DateTimeBegin = (DateTimeBegin - DateTimeBegin.TimeOfDay).AddHours(23); } else { DateTimeBegin = (DateTimeStart - DateTimeStart.TimeOfDay).AddHours(-1); } //Формировать запрос i = 0; m_strQuery = "SELECT ДатаВремя, "; foreach (GroupSignalsVzletNativeDSql.SIGNALMSTKKSNAMEsql s in m_arSignals) { m_strQuery += s.m_kks_name + ", "; } m_strQuery = m_strQuery.Remove(m_strQuery.Length - 2, 1); m_strQuery += " FROM " + NameTable + " "; m_strQuery += @"WHERE ДатаВремя > '" + DateTimeBegin + "' and ДатаВремя <= '" + DateTimeBegin.AddSeconds(PeriodMain.TotalSeconds) + "'"; //DateTimeBegin = DateTimeBegin.AddSeconds(secUTCOffsetToData); }
/// <summary> /// Установить содержание для запроса /// </summary> protected override void setQuery() { int idReq = HMath.GetRandomNumber() , i = -1; string cmd = string.Empty; long secUTCOffsetToData = m_msecUTCOffsetToServer / 1000; //перевод даты для суточного набора if (DateTimeStart != DateTimeBegin) { DateTimeBegin = (DateTimeBegin - DateTimeBegin.TimeOfDay).AddDays(PeriodMain.Days); } else { DateTimeBegin = (DateTimeStart - DateTimeStart.TimeOfDay); } //Формировать запрос i = 0; foreach (GroupSignalsKTSTUDsql.SIGNALIdsql s in m_arSignals) { if (s.IsFormula == false) { if (i == 0) { cmd = @"List"; } else if (i == 1) { cmd = @"ListAdd"; } m_strQuery += @"exec e6work.dbo.ep_AskVTIdata @cmd='" + cmd + @"'," + @"@idVTI=" + s.m_iIdLocal + @"," + @"@TimeStart='" + DateTimeBeginFormat + @"'," + @"@TimeEnd='" + DateTimeEndFormat + @"'," + @"@idReq=" + idReq + @";"; i++; } else { // формула ; } } m_strQuery += @"SELECT idVTI as [ID],idReq,TimeIdx,TimeRTC, DATEADD(Second," + secUTCOffsetToData + ",TimeSQL) as [DATETIME],idState,ValueFl as [VALUE],ValueInt,IsInteger,idUnit" + @", DATEDIFF(HH, GETDATE(), GETUTCDATE()) as [UTC_OFFSET]" + @" FROM e6work.dbo.VTIdataList" + @" WHERE idReq=" + idReq + @";"; m_strQuery += @"exec e6work.dbo.ep_AskVTIdata @cmd='" + @"Clear" + @"'," + @"@idReq=" + idReq + @";"; }
/// <summary> /// Формирование запроса /// </summary> protected override void setQuery() { int idReq = HMath.GetRandomNumber() ,i = -1; string cmd = string.Empty; //Формировать запрос i = 0; foreach (GroupSignalsKTSTUsql.SIGNALIdsql s in m_arSignals) { if (s.IsFormula == false) { if (i == 0) { cmd = @"List"; } else if (i == 1) { cmd = @"ListAdd"; } else { ; // оставить без изменений } m_strQuery += @"exec e6work.dbo.ep_AskVTIdata @cmd='" + cmd + @"'," + @"@idVTI=" + s.m_iIdLocal + @"," + @"@TimeStart='" + DateTimeBeginFormat + @"'," + @"@TimeEnd='" + DateTimeEndFormat + @"'," + @"@idReq=" + idReq + @";"; i++; } else { // формула ; } } m_strQuery += @"SELECT idVTI as [ID],idReq,TimeIdx,TimeRTC,TimeSQL as [DATETIME],idState,ValueFl as [VALUE],ValueInt,IsInteger,idUnit" + @", DATEDIFF(HH, GETDATE(), GETUTCDATE()) as [UTC_OFFSET]" + @" FROM e6work.dbo.VTIdataList" + @" WHERE idReq=" + idReq + @";"; m_strQuery += @"exec e6work.dbo.ep_AskVTIdata @cmd='" + @"Clear" + @"'," + @"@idReq=" + idReq + @";"; }
/// <summary> /// Установить содержание для запроса /// </summary> protected override void setQuery() { int idReq = HMath.GetRandomNumber() , i = -1; string cmd = string.Empty; //Формировать запрос i = 0; foreach (GroupSignalsKTSTUDsql.SIGNALIdsql s in m_arSignals) { if (s.IsFormula == false) { m_strQuery += string.Format(@"exec dbo.ep_AskVTIdata @cmd='{0}'" + @", @idVTI={1}" + @", @TimeStart='{2}'" + @", @TimeEnd='{3}'" + @", @idReq={4};" , i++ == 0 ? @"List" : @"ListAdd", s.m_iIdLocal, DateTimeBeginFormat, DateTimeEndFormat, idReq); } else { // формула ; } } // все поля idVTI, idReq, TimeIdx, TimeRTC, TimeSQL, idState, ValueFl, ValueInt, IsInteger, idUnit m_strQuery += string.Format(@"SELECT res.[idVTI] as [ID], SUM(res.[ValueFl]) as [VALUE]" + @", res.[DATETIME]" //+ @", {2} as [UTC_OFFSET]" //DATEDIFF(HOUR, GETDATE(), GETUTCDATE()) as [UTC_OFFSET] + @", COUNT(*) as [COUNT]" + @" FROM (" + @"SELECT [idVTI], [ValueFl]" + @", DATEADD(MINUTE, ceiling(DATEDIFF(MINUTE, DATEADD(DAY, DATEDIFF(DAY, 0, CAST('{0}' as datetime)), 0), [TimeSQL]) / 60.) * 60, DATEADD(DAY, DATEDIFF(DAY, 0, CAST('{0}' as datetime)), 0)) as [DATETIME]" + @" FROM [VTIdataList]" + @" WHERE idREQ = {1}" + @" GROUP BY [IdResult], [idVTI], [ValueFl]" + @", DATEADD(MINUTE, ceiling(DATEDIFF(MINUTE, DATEADD(DAY, DATEDIFF(DAY, 0, CAST('{0}' as datetime)), 0), [TimeSQL]) / 60.) * 60, DATEADD(DAY, DATEDIFF(DAY, 0, CAST('{0}' as datetime)), 0))" + @") res" + @" GROUP BY [idVTI], [DATETIME]" + @" ORDER BY [idVTI], [DATETIME];" , DateTimeBeginFormat, idReq); //, TimeSpan.FromSeconds(m_secOffsetUTCToData).Hours m_strQuery += string.Format(@"exec [dbo].ep_AskVTIdata @cmd='{0}'" + @", @idReq={1};", @"Clear", idReq); }
/// <summary> /// Функция проверки выполнения условий сигнализаций (для одного ГТП) /// </summary> /// <param name="curHour">Текущий час</param> /// <param name="curMinute">Текущий интервал (1-мин) - текущая минута указанного часа</param> /// <returns>Признак выполнения функции</returns> public int AlarmRegistred(int curHour, int curMinute) { //return EventAlarmDetect(m_tec.m_id, curHour, curMinute); //Признак выполнения функции int iRes = (int)HHandler.INDEX_WAITHANDLE_REASON.SUCCESS , iDebug = -1 //-1 - нет отладки, 0 - раб./отладка, 1 - имитирование , cntTGTurnOn = 0 // кол-во вкл. ТГ , cntTGTurnUnknown = allTECComponents[indxTECComponents].m_listLowPointDev.Count // кол-во ТГ с неизвестным состоянием , cntPower_TMValues = 0; //Счетчик кол-ва значений тек./мощн. ТГ в общем значении мощности для ГТП //Константы double TGTURNONOFF_VALUE = -1F //Значения для сигнализации "ТГ вкл./откл." , NOT_VALUE = -2F //НЕТ значения , power_TM = NOT_VALUE; //Признак состояния для сигнализации "ТГ вкл./откл." - исходный StatisticCommon.TG.INDEX_TURNOnOff curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN; //Список объектов, детализирующих событие сигнализации List <TecViewAlarm.AlarmTecViewEventArgs.EventDetail> listEventDetail = new List <TecViewAlarm.AlarmTecViewEventArgs.EventDetail>(); #region Код для отладки if (!(iDebug < 0)) { Console.WriteLine(@" - curHour=" + curHour.ToString() + @"; curMinute=" + curMinute.ToString()); } else { ; } #endregion Окончание блока кода для отладки //if (((lastHour == 24) || (lastHourError == true)) || ((lastMin == 0) || (lastMinError == true))) if (((curHour == 24) || (m_markWarning.IsMarked((int)INDEX_WARNING.LAST_HOUR) == true)) || ((curMinute == 0) || (m_markWarning.IsMarked((int)INDEX_WARNING.LAST_MIN) == true))) { Logging.Logg().Error(@"TecView::AlarmEventRegistred (" + m_tec.name_shr + @"[ID_COMPONENT=" + m_ID + @"])" + @" - curHour=" + curHour + @"; curMinute=" + curMinute, Logging.INDEX_MESSAGE.NOT_SET); } else { foreach (StatisticCommon.TG tg in allTECComponents[indxTECComponents].m_listLowPointDev) { curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN; #region Код для отладки if (!(iDebug < 0)) { Console.Write(tg.m_id_owner_gtp + @":" + tg.m_id + @"=" + m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM); } else { ; } #endregion Окончание блока кода для отладки if (m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM < 1F) { //??? проверять ли значение на '< 0F' if (!(m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM < 0F)) { curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.OFF; } else { ; //??? неопределенное состояние ТГ } } else {//Больше ИЛИ равно 1F curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.ON; // подготовить значение if (power_TM == NOT_VALUE) { power_TM = 0F; } else { ; } // учесть в общем значении мощности ГТП, текущую мощность ТГ power_TM += m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM; // увеличить счетчик cntPower_TMValues++; } //??? неизвестный идентификатор источника значений СОТИАССО (id_tm = -1) listEventDetail.Add(new TecViewAlarm.AlarmTecViewEventArgs.EventDetail() { id = tg.m_id , value = m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM , last_changed_at = m_dictValuesLowPointDev[tg.m_id].m_dtCurrent_TM , id_tm = m_dictValuesLowPointDev[tg.m_id].m_id_TM }); #region Код для отладки //Имитирование - изменяем состояние if (iDebug == 1) { if (!(tg.m_TurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN)) { if (curTurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.ON) {// имитация - ТГ выкл. //Учесть мощность выключенного ТГ в значении для ГТП в целом power_TM -= m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM; //Присвоить значение для "отладки" (< 1) m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM = 0.666F; //Изменить состояние curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.OFF; } else if (curTurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.OFF) { //Присвоить значение для "отладки" (> 1) m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM = 66.6F; //Изменить состояние curTurnOnOff = StatisticCommon.TG.INDEX_TURNOnOff.ON; } else { ; } Console.Write(Environment.NewLine + @"Отладка:: " + tg.m_id_owner_gtp + @":" + tg.m_id + @"=" + m_dictValuesLowPointDev[tg.m_id].m_powerCurrent_TM + Environment.NewLine); } else { ; } } else { ; } #endregion Окончание блока кода для отладки if (!(curTurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN)) { if (tg.m_TurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN) { tg.m_TurnOnOff = curTurnOnOff; } else if (!(tg.m_TurnOnOff == curTurnOnOff)) { // EventReg(new TecViewAlarm.AlarmTecViewEventArgs(tg.m_id, new AlarmNotifyEventArgs.EventReason() { value = listEventDetail[listEventDetail.Count - 1].value , UDGe = m_valuesHours[curHour].valuesUDGe , koeff = TECComponentCurrent.m_dcKoeffAlarmPcur } , DateTime.UtcNow , (int)curTurnOnOff , listEventDetail)); //Прекращаем текущий цикл... //Признак досрочного прерывания цикла для сигн. "Текущая P" power_TM = TGTURNONOFF_VALUE; break; } else { ; //Состояние ТГ не изменилось } } else { //Текущее состояние ТГ не удалось определить Logging.Logg().Warning(@"TecViewAlarm::AlarmRegistred (id_tg=" + tg.m_id + @") - Detail: " + listEventDetail[listEventDetail.Count - 1].ValuesToString() , Logging.INDEX_MESSAGE.NOT_SET); } if (!(tg.m_TurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.UNKNOWN)) { cntTGTurnUnknown--; if (tg.m_TurnOnOff == StatisticCommon.TG.INDEX_TURNOnOff.ON) { cntTGTurnOn++; } else { ; } } else { ; } #region Код для отладки if (!(iDebug < 0)) { if ((TECComponentCurrent.m_listLowPointDev.IndexOf(tg) + 1) < TECComponentCurrent.m_listLowPointDev.Count) { Console.Write(@", "); } else { ; } } else { ; } #endregion Окончание блока кода для отладки } if (!(power_TM == TGTURNONOFF_VALUE)) { if ((!(power_TM == NOT_VALUE)) && (!(power_TM < 1))) { int situation = 0; #region Код для отладки if (!(iDebug < 0)) { situation = HMath.GetRandomNumber() % 2 == 1 ? -1 : 1; EventReg(new TecViewAlarm.AlarmTecViewEventArgs(TECComponentCurrent.m_id , new AlarmNotifyEventArgs.EventReason() { value = listEventDetail[0].value , UDGe = m_valuesHours[curHour].valuesUDGe , koeff = TECComponentCurrent.m_dcKoeffAlarmPcur } , DateTime.UtcNow , situation , listEventDetail)); //Меньше Console.WriteLine(@"; ::AlarmEventRegistred () - EventReg [ID=" + TECComponentCurrent.m_id + @"] ..."); } else #endregion Окончание блока кода для отладки { if ((cntTGTurnUnknown == 0) && // кол-во ТГ с неизвестным состоянием = 0 (cntTGTurnOn == cntPower_TMValues)) // кол-во ТГ, учтенных для подсчета общего знач. тек./мощн. ГТП = кол-ву вкл. ТГ { double absDiff = Math.Abs(power_TM - m_valuesHours[curHour].valuesUDGe) , lim = m_valuesHours[curHour].valuesUDGe * ((double)TECComponentCurrent.m_dcKoeffAlarmPcur / 100); if (absDiff > lim) { //EventReg(allTECComponents[indxTECComponents].m_id, -1); if (power_TM < m_valuesHours[curHour].valuesUDGe) { situation = -1; //Меньше } else { situation = 1; //Больше } EventReg(new TecViewAlarm.AlarmTecViewEventArgs(TECComponentCurrent.m_id , new AlarmNotifyEventArgs.EventReason() { value = power_TM , UDGe = m_valuesHours[curHour].valuesUDGe , koeff = TECComponentCurrent.m_dcKoeffAlarmPcur } , DateTime.UtcNow , situation , listEventDetail)); } else { ; //EventUnReg... } } else { // обработаны не все значения тек./мощности ТГ_в_работе из состава ГТП Logging.Logg().Warning(@"TecViewAlarm::AlarmRegistred (id=" + m_ID + @") - обработаны не все значения тек./мощности ТГ_в_работе из состава ГТП", Logging.INDEX_MESSAGE.NOT_SET); } } } else { ; //Нет значений ИЛИ значения ограничены 1 МВт } } else { iRes = -102; //(int)INDEX_WAITHANDLE_REASON.BREAK; } #region Код для отладки if (!(iDebug < 0)) { Console.WriteLine(); } else { ; } ////Отладка //for (int i = 0; i < m_valuesHours.valuesFact.Length; i ++) // Console.WriteLine(@"valuesFact[" + i.ToString() + @"]=" + m_valuesHours.valuesFact[i]); #endregion Окончание блока кода для отладки } return(iRes); }
/// <summary> /// Целевая функция контроля /// </summary> private void targetFunc() { //Logging.Logg().Debug(@"StateManager::targetFunc () - итерация контроля; кол-во объектов=" + m_listObjects.Count + @" ...", Logging.INDEX_MESSAGE.NOT_SET); DateTime now = DateTime.Now; double msecLimit = -1F , msecCurrent = -1F; List <int> listIdCrashed = null; List <ID?> listIDToReload = null; ID id; //_lIdCurrentTargetFunc = HMath.GetRandomNumber(); _listOTargetFunc.Add(new OTargetFunc() { m_lId = HMath.GetRandomNumber(), m_datetime = DateTime.Now }); while (_listOTargetFunc.Count > StateManager.MAX_HISTORY_INFOCRASHED) { _listOTargetFunc.RemoveAt(0); } #if _SEPARATE_APPDOMAIN if (m_stateManager.IsReload == true) { // выгрузка/загрузка по расписанию listIDToReload = new List <ID?>(); foreach (OManagement o in m_listObjects) { if (listIDToReload.Find(item => { return((item.GetValueOrDefault().m_typeOwner == o.m_id.m_typeOwner) && (item.GetValueOrDefault().m_idOwner == o.m_id.m_idOwner)); }) == null) { listIDToReload.Add(new ID(new object[] { o.m_id.m_typeOwner, o.m_id.m_idOwner, -1 })); } else { ; } } foreach (ID item in listIDToReload) { // выгрузка библиотеки БЕЗ корректного останова eventCrashed(new EventCrashedArgs(item, true)); } } else { #endif foreach (OManagement o in m_listObjects) { msecLimit = 0; // признак необходимости проверки объекта в текущей итерации switch (o.m_state) { case STATE.CONTROLED: msecLimit = (int)o.m_tsLimit.TotalMilliseconds; break; case STATE.ADDED: case STATE.REMOVED: case STATE.CRASH: msecLimit = (int)StateManager.s_tsWaitConfirmed.Value.TotalMilliseconds; break; default: break; } msecCurrent = (now - o.m_dtUpdate).TotalMilliseconds; //Debug.WriteLine(string.Format(@"{0}- {1}, STATE={2} [CURRENT={3}, LIMIT={4}]" // , DateTime.Now.ToString() // , o.m_id.ToPrint(), o.m_state // , msecCurrent, msecLimit)); if ((msecLimit > 0) && (msecCurrent > msecLimit)) { switch (o.m_state) { case STATE.CONTROLED: o.SetCrashed(); break; case STATE.ADDED: case STATE.REMOVED: o.SetFCrashed(); break; case STATE.CRASH: //??? почему не ForceCrashed. Т.к. 'eventCrashed' принимается на основе 2-х подряд STATE::CRASH default: break; } m_dictInfoCrashed.MarkedItem(o.m_id, o.m_state); } else { ; } } foreach (KeyValuePair <KeyValuePair <FormMain.INDEX_SRC, int>, DictOManagementInfoCrashed> pair in m_dictInfoCrashed) { #if _SEPARATE_APPDOMAIN if (pair.Value.IsForceReload == true) { id = new ID(new object[] { pair.Key.Key, pair.Key.Value, -1 }); // восстановить признак pair.Value.IsForceReload = false; //??? самостоятельно выполнить ремове OManagement m_listObjects.DeleteItems(id); // выгрузка библиотеки АВАРИЙНО (БЕЗ корректного останова) eventCrashed(new EventCrashedArgs(id, true)); } else { #endif listIdCrashed = pair.Value.GetListIDCrashed(); if (listIdCrashed.Count > 0) #if _SEPARATE_APPDOMAIN { if (listIdCrashed.Count > StateManager.MAX_COUNT_CRASHED_TO_RELOAD_GROUPSOURCES) { // выгрузка библиотеки ШТАТНО (с корректным остановом) eventCrashed(new EventCrashedArgs(new ID(new object[] { pair.Key.Key, pair.Key.Value, -1 }), false)); } else #endif { foreach (int item in listIdCrashed) { id = new ID(new object[] { pair.Key.Key, pair.Key.Value, item }); // стоп/старт объекта контроля eventCrashed(new EventCrashedArgs(id, false)); } } else { ; } #if _SEPARATE_APPDOMAIN } #endif } } }
public void New() { m_Id = HMath.GetRandomNumber(); }
/// <summary> /// Копировать XML-документ /// </summary> /// <param name="source">Источник для копирования</param> /// <returns>Копия аргумента</returns> public static XmlDocument GenerateXmlDocument(XmlDocument source) { string[] patterns = { @"TIME", @"DATETIME", @"VALUE_FLOAT", @"VALUE_INT" }; string occurence = string.Empty; int indx = -1; XmlDocument xmlDocRes = CopyXmlDocument(source); foreach (string pattern in patterns) { occurence = string.Format(@"?{0}?", pattern); indx = 0; while (true) { indx = xmlDocRes.InnerXml.IndexOf(occurence, indx); if (!(indx < 0)) { switch (pattern) { case @"TIME": xmlDocRes.InnerXml = xmlDocRes.InnerXml.Replace(occurence, DateTime.UtcNow.ToString(@"HH:mm:ss.fff")); break; case @"DATETIME": xmlDocRes.InnerXml = xmlDocRes.InnerXml.Replace(occurence, DateTime.UtcNow.ToString()); break; case @"VALUE_FLOAT": xmlDocRes.InnerXml = xmlDocRes.InnerXml.Remove(indx, occurence.Length); xmlDocRes.InnerXml = xmlDocRes.InnerXml.Insert(indx, string.Format(@"{0:F2}", HMath.GetRandomNumber(5, 655))); break; case @"VALUE_INT": xmlDocRes.InnerXml = xmlDocRes.InnerXml.Remove(indx, occurence.Length); xmlDocRes.InnerXml = xmlDocRes.InnerXml.Insert(indx, string.Format(@"{0}", HMath.GetRandomNumber(656, 998))); break; default: break; } } else { break; } } } return(xmlDocRes); }
/// <summary> /// Целевая функция контроля /// </summary> private void targetFunc() { //Logging.Logg().Debug(@"StateManager::targetFunc () - итерация контроля; кол-во объектов=" + m_listObjects.Count + @" ...", Logging.INDEX_MESSAGE.NOT_SET); DateTime now = DateTime.Now; int msecLimit = -1; _lIdCurrentTargetFunc = HMath.GetRandomNumber(); foreach (OManagement o in m_listObjects) { msecLimit = 0; // признак необходимости проверки объекта в текущей итерации switch (o.m_state) { case STATE.ADDED: case STATE.REMOVED: msecLimit = MSEC_CONFIRM_WAIT; break; case STATE.CONTROLED: msecLimit = (int)o.m_tsLimit.TotalMilliseconds; break; default: break; } if ((msecLimit > 0) && (now - o.m_dtUpdate).TotalMilliseconds > msecLimit) { //Пополнить словарь событиями-нарушениями //new Thread (new ParameterizedThreadStart (onEvtCrashed)).Start(new EventCrashedArgs() { m_id = o.m_id, m_state = o.m_state }); eventCrashed(new EventCrashedArgs() { m_id = o.m_id, m_state = o.m_state }); //onEvtCrashed(new EventCrashedArgs() { m_id = o.m_id, m_state = o.m_state }); //Console.WriteLine(@"HHandlerQueue::targetFunc () - eventCrashed (id=" + o.m_id.m_idOwner // + @", key=" + o.m_id.m_idGroupSgnls // + @", state=" + o.m_state.ToString () + @") - ..."); // исключить из следующей проверки o.SetCrashed(); //o.Update(); } else { ; } } foreach (KeyValuePair <KeyValuePair <INDEX_SRC, int>, DictOManagementInfoCrashed> pair in m_dictInfoCrashed) { if (pair.Value.IsCrashed == true) { pushCommandReloadGroupSources(pair.Key.Key, pair.Key.Value); } else { pushStateChangedGroupSignals(new ID(new object[] { pair.Key.Key, pair.Key.Value, pair.Value.GetIdCrashed() })); } } }