using DevExpress.Xpo; using Ips.Sps.Tsks; using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Threading.Tasks; using Ips.Library.Basic; using Ips.Sps.Scheduling.Entities; using Ips.Library.Entity; using Ips.Sps.Ants; using Ips.Sps.Sats; using System.Configuration; using Ips.Sps.TskResults.Stses; using Ips.Library.LocLib; namespace Ips.Sps.Scheduling { public class TskScheduler { public static readonly TskScheduler Default = new TskScheduler(); public TskScheduler() { _tskManager = TskManager.Default; } TskManager _tskManager; private static readonly object locker = new object(); List _runTskList = new List(); ConcurrentDictionary _runHanderList = new ConcurrentDictionary(); public void Start(int tskId) { if (_runTskList.Any(m => m.TskId == tskId)) { throw new Exception("任务已在运行中!"); } Session _session = new Session(); var tsk = _session.GetObjectByKey(tskId); if (tsk == null) throw new Exception("任务不存在!"); if (tsk.AdCardList.ToList().IsNullOrEmpty()) throw new Exception("任务采集卡不存在!"); if (tsk.SignalList.ToList().IsNullOrEmpty() && tsk.RefSignalList.ToList().IsNullOrEmpty()) throw new Exception("任务信号不存在!"); var runTsk = BuildRunTsk(tsk, _session); if (runTsk != null) { QueueTsk(runTsk); ExecuteTsk(runTsk); } } public void Stop(int tskId) { if (_runHanderList.ContainsKey(tskId)) { _runHanderList[tskId].Stop(); _tskManager.UpdateTskState(tskId, TskState.Stopping); IpsLogger.Info($"任务【{_runHanderList[tskId]._tsk.TskName}】停止中..."); } else { var tskContext = _runTskList.FirstOrDefault(m => m.TskId == tskId); if (tskContext == null) return; TskStop(tskContext); } } public void StopAll(bool wait = false) { while (_runTskList.Any()) { Stop(_runTskList[0].TskId); } if (wait) { while (_runTskList.Any()) { Task.Delay(500).Wait(); } } } public List GetRunTskList() { return _runTskList; } protected virtual RunTsk BuildRunTsk(Tsk tsk, Session _session) { RunTsk _runTsk = new RunTsk(); _runTsk.TskId = tsk.Oid; _runTsk.TskName = tsk.Name; _runTsk.WorkTime = DateTime.Now; _runTsk.DfLoc = tsk.DfLoc; _runTsk.IsHistory = tsk.IsHistory; _runTsk.TskType = tsk.Strategy.TskType; _runTsk.SigType = tsk.Strategy.SigType; _runTsk.AdMode = tsk.Strategy.AdMode; if (tsk.IsHistory) { //_runTsk.FileFindType = tsk.Strategy.AdMode == AdMode.DDCKeep ? SigFileFindType.ByFS : SigFileFindType.ByDB; _runTsk.FileFindType = SigFileFindType.ByFS; } _runTsk.StartTime = tsk.StartTime; _runTsk.StopTime = tsk.EndTime; _runTsk.SigTime = DateTime.MinValue; var runCard = _runTsk.AdCard = new RunAdCard(); var adCard = tsk.AdCardList.First(); runCard.CardId = adCard.Oid; runCard.CardName = adCard.Name; runCard.CardCode = adCard.Code ?? string.Empty; runCard.CardType = adCard.CardType; runCard.TriggerMode = adCard.TriggerMode; runCard.ClockType = adCard.ClockerType; runCard.ClockFreq = adCard.ClockFreq.E6(); runCard.DdcFreq = adCard.DdcFreq.E6(); if (tsk.Strategy.AdMode != AdMode.ADC) { runCard.Mutil = adCard.Mutil; } else { runCard.Mutil = 1; } runCard.StorePath = adCard.StorePath; var antIds = adCard.Channels.Select(m => m.AntId).Distinct(); var antList = _session.Query().Where(m => antIds.Contains(m.Oid)).ToList(); var satIds = adCard.Channels.SelectMany(m => m.GetSatIds()).Distinct(); var satList = _session.Query().Where(m => satIds.Contains(m.Oid)).ToList(); foreach (var adch in adCard.Channels) { var runCh = new RunAdCh(); runCh.ChId = adch.Oid; runCh.ChNum = adch.ChNum; runCh.FixCenter = adch.FixCenter; runCh.CenterFreq = adch.CenterFreq.E6l(); runCh.FrqAddr = adch.FrqAddr; runCh.FrqTurn = adch.FrqTurn.E6l(); runCh.AdcCode = adCard.Code; runCh.AntId = adch.AntId; var ant = antList.FirstOrDefault(m => m.Oid == adch.AntId); if (ant != null) { runCh.AntName = ant.Name; runCh.AntCode = ant.Code; runCh.AntLon = ant.Lon; runCh.AntLat = ant.Lat; runCh.AntAlt = ant.Alt; } if (adch.SatIds.IsNotNullOrWhitespace()) { var chSatIds = adch.GetSatIds(); chSatIds.ForEach(satid => { var sat = satList.FirstOrDefault(m => m.Oid == satid); if (sat != null) { var runSat = new RunSat(); runSat.SatId = sat.Oid; runSat.SatNum = sat.SatNum; runSat.SatName = sat.Name; runSat.SatType = sat.SatType; runSat.SatCode = sat.SatNum.ToString(); runSat.SatTurn = sat.SatTurn.E6l(); runCh.Sats.Add(runSat); } }); } runCard.Channels.Add(runCh); } var tarSigList = tsk.SignalList.OrderBy(m => m.SigFreq).ThenBy(m => m.BandWidth).ToList(); var refSigList = tsk.RefSignalList.OrderBy(m => m.SigFreq).ThenBy(m => m.BandWidth).ToList(); List mainSatIds = new List(); foreach (var tskSig in tarSigList.Concat(refSigList)) { RunSig sig = new RunSig(); sig.SigId = tskSig.Oid; sig.SigCategory = tskSig.SigCategory; sig.SigType = tskSig.SigType; sig.SigFreq = tskSig.SigFreq.E6l(); sig.FreqStart = tskSig.FreqStart.E6l(); sig.FreqEnd = tskSig.FreqEnd.E6l(); sig.FreqStep = tskSig.FreqStep.E3(); sig.BandWidth = tskSig.BandWidth.E3(); sig.SigLen = tskSig.SigLen; sig.MainSatId = tskSig.MainSatId ?? 0; mainSatIds.Add(sig.MainSatId); if (tskSig.AdjaSatIds.IsNotNullOrWhitespace()) { sig.AdjaSatIds = tskSig.AdjaSatIds.Split(',').Select(m => int.Parse(m)).ToList(); } else { sig.AdjaSatIds = adCard.Channels .Where(m => !m.GetSatIds().Any(m => m == sig.MainSatId)) .SelectMany(m => m.GetSatIds()) .ToList(); } sig.HasRange = tskSig.HasRange; sig.SigLon = tskSig.HasRange ? tskSig.SigLon : 0; sig.SigLat = tskSig.HasRange ? tskSig.SigLat : 0; sig.SigAlt = tskSig.SigAlt; sig.LonRange = tskSig.HasRange ? tskSig.LonRange : 360; sig.LatRange = tskSig.HasRange ? tskSig.LatRange : 180; sig.EmtId = tskSig.EmtId ?? 0; if (sig.EmtId > 0) { var emt = _session.GetObjectByKey(sig.EmtId); if (emt != null) { sig.SigEmtCode = emt.Code; sig.SigEmtName = emt.Name; sig.SigEmtType = emt.EmtType; sig.SigEmtSpeed = emt.Speed; if (emt.HasSample) { var samples = emt.SigSamples .Where(m => m.Enable && m.SigFreq == tskSig.SigFreq && m.BandWidth == tskSig.BandWidth) .ToList(); foreach (var smpl in samples) { RunSigSample runSmpl = new RunSigSample(); runSmpl.SampleId = smpl.Oid; runSmpl.SigFreq = smpl.SigFreq.E6l(); runSmpl.BandWidth = smpl.BandWidth.E3(); runSmpl.Fs = smpl.Fs; runSmpl.StartSec = smpl.StartSec; runSmpl.EndSec = smpl.EndSec; runSmpl.SampleFile = smpl.SampleFile; sig.SigSamples.Add(runSmpl); } } if (emt.EmtType == EmtType.FixSation && !sig.HasRange) { sig.SigLon = emt.Lon; sig.SigLat = emt.Lat; sig.LonRange = 6; sig.LatRange = 6; } sig.SigAlt = sig.HasRange ? sig.SigAlt : emt.Alt; sig.HasSample = sig.SigSamples.IsNotNullOrEmpty(); } } sig.Fs = SigCalcUtil.CalcFs(runCard.ClockFreq, sig.BandWidth, runCard.Mutil); if (sig.SigCategory != SignalCategory.RefSig) { _runTsk.TarSigList.Add(sig); } else { _runTsk.RefSigList.Add(sig); } } var dxSigList = tsk.DxSignalList.OrderBy(m => m.SigFreq).ThenBy(m => m.BandWidth).ToList(); mainSatIds= mainSatIds.Distinct().ToList(); foreach (var dxSig in dxSigList) { DxSig dx = new DxSig(); dx.DxSigId = dxSig.Oid; dx.SigType = dxSig.SigType; dx.SigFreq = dxSig.SigFreq.E6l(); dx.BandWidth = dxSig.BandWidth.E3(); if (dxSig.AdjaSatIds.IsNotNullOrWhitespace()) { dx.AdjaSatIds = dxSig.AdjaSatIds.Split(',').Select(m => int.Parse(m)).ToList(); } else { dx.AdjaSatIds = adCard.Channels .Where(m => !m.GetSatIds().Any(m => mainSatIds.Contains(m))) .SelectMany(m => m.GetSatIds()) .ToList(); } _runTsk.DxSigList.Add(dx); } return _runTsk; } protected virtual void QueueTsk(RunTsk runTsk) { _runTskList.Add(runTsk); _tskManager.UpdateTskState(runTsk.TskId, TskState.Wait); IpsLogger.Info($"任务【{runTsk.TskName}】已添加到执行队列..."); } protected virtual void ExecuteTsk(RunTsk runTsk) { if (_runHanderList.Any()) return; TskHandler tskHandler = new TskHandler(runTsk); tskHandler.Start().ContinueWith(TskHandleCompleted, tskHandler); _runHanderList.TryAdd(runTsk.TskId, tskHandler); _tskManager.UpdateTskState(runTsk.TskId, TskState.Running); IpsLogger.Info($"任务【{runTsk.TskName}】开始执行..."); } protected virtual void TskHandleCompleted(Task tsk, object state) { var handler = state as TskHandler; if (handler == null) return; _runHanderList.Remove(handler._tsk.TskId, out _); if (handler._tsk.SigTime >= handler._tsk.StopTime || handler.IsCancelled) { TskStop(handler._tsk); } else { _tskManager.UpdateTskState(handler._tsk.TskId, TskState.Wait); } lock (locker) { //按ID排序,查找下一个任务上下文 var nextContext = _runTskList.Where(m => m.TskId < handler._tsk.TskId) .OrderByDescending(m => m.TskId) .FirstOrDefault(); if (nextContext == null) nextContext = _runTskList.OrderByDescending(m => m.TskId).FirstOrDefault(); if (nextContext != null) ExecuteTsk(nextContext); } } protected virtual void TskStop(RunTsk runTsk) { _runTskList.Remove(runTsk); _tskManager.UpdateTskState(runTsk.TskId, TskState.Stop); IpsLogger.Info($"任务【{runTsk.TskName}】已停止"); } } }