//Чтение значений из источника internal ValuesCount ReadValues() { var vcount = new ValuesCount(); try { SourceConnect.ClearSignalsValues(false); using (Start(5, 10)) if (!Connect() || !Prepare()) { return(new ValuesCount(VcStatus.Fail)); } vcount = ReadProviderValues(); //Вычисление значений расчетных сигналов if (SourceConnect.CalcSignals.Count > 0) { AddEvent("Вычисление значений расчетных сигналов"); int calc = 0; foreach (var sig in SourceConnect.CalcSignals.Values) { sig.Calculate(); calc += sig.OutValue.Count; } AddEvent("Значения расчетных сигналов прочитаны", calc + " значений сформировано"); vcount.WriteCount += calc; } AddEvent("Значения из источника прочитаны", vcount.ToString()); } catch (Exception ex) { AddError("Ошибка при чтении значений из источника", ex); return(vcount.AddStatus(VcStatus.Fail)); } finally { AddErrorOutsWarning(); PrevProcessEnd = PeriodEnd; } return(vcount); }
//Чтение значений из провайдера protected override ValuesCount ReadProviderValues() { var vcount = new ValuesCount(); AddEvent("Чтение среза значений"); using (Start(10, PeriodBegin == PeriodEnd ? 90 : 40)) vcount += ReadCut(); foreach (ListSignal sig in SourceConnect.InitialSignals.Values) { vcount.WriteCount += sig.MakeBegin(); } AddEvent("Срез значений получен", vcount.ToString()); if (vcount.Status == VcStatus.Fail) { return(vcount); } //Чтение изменений if (PeriodBegin < PeriodEnd) { AddEvent("Чтение изменений значений"); var ts = PeriodEnd.Subtract(PeriodBegin).Subtract(new TimeSpan(0, 0, 0, 0, 1)); var tts = new TimeSpan(0); int n = 0; while (tts < ts) { tts = tts.Add(PeriodLimit); n++; } var changes = new ValuesCount(); using (Start(40, 85)) { DateTime beg = PeriodBegin; DateTime en = Static.MinDate; double proc = 0; while (en < PeriodEnd) { using (Start(proc, proc += 100.0 / n)) { en = beg.Add(PeriodLimit); if (PeriodEnd < en) { en = PeriodEnd; } changes = changes + ReadChanges(beg, en); beg = en; } } } foreach (ListSignal sig in SourceConnect.InitialSignals.Values) { changes.WriteCount += sig.MakeEnd(); } AddEvent("Изменения значений получены", changes.ToString()); vcount += changes; if (vcount.IsFail) { return(vcount); } Procent = 90; } return(vcount); }
//Чтение значений по блокам объектов protected ValuesCount ReadByParts(IEnumerable <ListSourceOut> objects, //список объектов int partSize, //Размер одного блока DateTime beg, DateTime en, //Период считывания bool isCut, //Считывается срез Func <List <ListSourceOut>, DateTime, DateTime, bool, ValuesCount> readPartFun, //Функция чтения значений по одному блоку string msg = null) //Сообщение для истории о запуске чтения данных { var valuesCount = new ValuesCount(); try { int n; var parts = MakeParts(objects, partSize, isCut, out n); if (n == 0) { AddEvent("Пустой список объектов для считывания" + (isCut ? " среза" : ""), beg + " - " + en); return(valuesCount); } if (!Connect()) { return(valuesCount.AddStatus(VcStatus.Fail)); } AddEvent(msg ?? "Чтение " + (isCut ? "среза" : "изменений") + " значений сигналов", n + " объектов, " + beg + " - " + en); var success = new bool[parts.Count]; int errCount = 0, consErrCount = 0; double d = 70.0 / parts.Count; for (int i = 0; i < parts.Count; i++) { string text = "Чтение блока значений, " + parts[i][0].Context + (parts[i].Count == 0 ? "" : " и др."); using (StartIndicatorText(Procent, Procent + d, text)) using (StartKeep(0, 100)) { var vc = new ValuesCount(); try { vc += readPartFun(parts[i], beg, en, isCut); } catch (Exception ex) { vc.AddStatus(VcStatus.NoSuccess); AddWarning("Ошибка при чтении блока значений", ex); } success[i] = vc.Status == VcStatus.Success || vc.Status == VcStatus.Undefined; valuesCount += vc; if (vc.Status != VcStatus.Fail && vc.Status != VcStatus.NoSuccess) { AddEvent("Значения блока объектов прочитаны", vc.ToString()); consErrCount = 0; } else { errCount++; consErrCount++; AddWarning("Значения блока объектов не были прочитаны", null, vc.ToString()); if (consErrCount == 1 && !Reconnect()) { return(valuesCount.AddStatus(VcStatus.Fail)); } if (consErrCount > 2) { AddError("Значения с источника не были прочитаны", null, valuesCount.ToString()); return(valuesCount.AddStatus(VcStatus.Fail)); } } } } if (errCount == 0) { AddEvent("Значения с источника прочитаны", valuesCount.ToString()); return(valuesCount); } AddEvent("Рекурсивное чтение значений по блокам объектов"); valuesCount.Status = VcStatus.Undefined; d = 30.0 / parts.Count; for (int i = 0; i < parts.Count; i++) { using (Start(Procent, Procent + d)) if (!success[i]) { valuesCount += ReadPartRecursive(parts[i], beg, en, isCut, readPartFun); } } } catch (Exception ex) { AddError("Ошибка при получении данных", ex); return(valuesCount.AddStatus(VcStatus.Fail)); } return(valuesCount); }
//Рекурсивное чтение значений по блоку private ValuesCount ReadPartRecursive(List <ListSourceOut> part, //Блок сигналов DateTime beg, DateTime en, //Период считывания bool isCut, //Считывается срез Func <List <ListSourceOut>, DateTime, DateTime, bool, ValuesCount> readPartFun) //Функция чтения значений по одному блоку { int n = 0; int errCount = 0; var valuesCount = new ValuesCount(); var queue = new Queue <List <ListSourceOut> >(); queue.Enqueue(part); while (queue.Count > 0) { string text = "Рекурсивное чтение блока значений, " + part[0].Context + (part.Count == 0 ? "" : " и др."); using (StartIndicatorText(n < 10 ? 10 * n : 90, n < 9 ? 10 * (n + 1) : 90, text)) using (StartKeep(0, 100)) { var p = queue.Dequeue(); n++; Procent = n < 10 ? 10 * n : 90; if (n == 8 && errCount == 7) { AddWarning("Значения по блоку объектов не прочитаны"); return(valuesCount); } AddEvent("Чтение " + (isCut ? "среза" : "изменений") + " значений сигналов", p.Count + " выходов"); var vc = new ValuesCount(); try { vc = readPartFun(p, beg, en, isCut); } catch (Exception ex) { vc.AddStatus(VcStatus.NoSuccess); AddWarning("Ошибка при чтении блока значений", ex); } valuesCount += vc; if (!vc.IsFail) { AddEvent("Значения прочитаны", vc.ToString()); } else { AddWarning("Значения не прочитаны"); errCount++; if (p.Count > 1) { if (errCount == 1 && !Reconnect()) { return(valuesCount.AddStatus(VcStatus.Fail)); } int m = p.Count / 2; queue.Enqueue(p.GetRange(0, m)); queue.Enqueue(p.GetRange(m, part.Count - m)); } else { AddErrorOut(p[0].Context, KeepedError); } } } } return(valuesCount); }