/// <summary> /// Создаёт новый экземпляр класса <see cref="Calculator"/>. /// </summary> /// <param name="ci">Постановка задачи</param> /// <param name="mat">Список материалов</param> /// <param name="sav">Параметры сохранения результатов</param> /// <param name="pc">Информатор о текущем состоянии расчёта</param> public Calculator(ComputeItem ci, List <Material> mat, Saver sav, Action <byte> pc = null) { percentCallback = pc ?? (_ => {; }); computeItem = ci; // Нулевой элемент - воздух materials = Enumerable.Repeat(Material.Air, 1).Concat(mat).ToArray(); saver = sav; stopFlag = false; }
private void Calc(ComputeItem ci, QMSetting setting) { AddRepString(false, "TS", MessageReader.GetMessage("Msg:T:Start", taskNomber, ci.Name ?? String.Empty), false); var startTime = DateTime.Now; int percent = 0; bool percentRefreshed = true; var lastConnect = startTime; // хранит время последнего выхода процесса на связь string dname = Path.Combine(resDir, startTime.ToString("yyyyMMddHHmmssfff")); if (!string.IsNullOrWhiteSpace(ci.Name)) { dname += "[" + new string(ci.Name.Trim().Select(c => (System.IO.Path.GetInvalidFileNameChars().Contains(c)) ? '_' : c).ToArray()) + "]"; } var saver = new Saver(dname); AddRepString(false, "TDir", dname); int mfi = 1; ci.BaseMaterials = ci.BaseMaterials.ToArray(); // копия массива ci.OverheadMaterials = ci.OverheadMaterials.ToArray(); var usingmat = materials.Concat(outML).Where((_, i) => { var bi = ci.BaseMaterials.ToList().BinarySearch(i + 1); var oi = ci.OverheadMaterials.ToList().BinarySearch(i + 1); if (bi >= 0) { ci.BaseMaterials[bi] = mfi; } if (oi >= 0) { ci.OverheadMaterials[oi] = mfi; } if (oi >= 0 || bi >= 0) { ++mfi; return(true); } return(false); }).ToList(); { var sqm = new QueueManager(); sqm.materials = usingmat; sqm.queue.Add(ci); QueueManager.SaveToFile(Path.Combine(dname, taskFileName), sqm); } setting.preCICalc(taskNomber, ci.Name, startTime); var calculator = new Calculator(ci, usingmat, saver, x => { percent = x; percentRefreshed = true; lastConnect = DateTime.Now; }); bool error = false; string msg = ""; try { Task calc = new Task(calculator.Calculate); calc.Start(); while (!calc.IsCompleted) { calc.Wait(2000, new CancellationToken(stopFlag)); if (calc.IsFaulted) { throw calc.Exception; } if (percentRefreshed) { percentRefreshed = false; setting.CIPCRef((byte)percent, lastConnect); setting.CISUpd(QMSetting.WorkStatus.Run); } if (DateTime.Now.Subtract(lastConnect).TotalMinutes > 10) { setting.CISUpd(QMSetting.WorkStatus.Lag); } } } catch (Exception e) { error = true; msg = ErrorLogger.Log(e); } ((IDisposable)saver).Dispose(); if (error) { setting.CISUpd(QMSetting.WorkStatus.Error); setting.postCIError(msg); AddRepString(true, "TErr", msg, false); AddRepString(false, "TEF", MessageReader.GetMessage("Msg:T:FinError", taskNomber, percent), false); } else { setting.CISUpd(QMSetting.WorkStatus.Complete); setting.postCIGood(); AddRepString(false, "TF", MessageReader.GetMessage("Msg:T:Fin", taskNomber), false); } setting.postCIAny(); }