Exemplo n.º 1
0
 /// <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();
        }