using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; namespace WCS.Core { public abstract class SystemBase : DescriptionClass { public World World { get; private set; } public SystemBase() { var attr = this.GetType().GetCustomAttribute(); if (attr == null) return; var wt = attr.WorldType; World = World.Worlds.First(v => v.GetType() == wt); } public abstract List GetObjects(); public abstract void Update(List list); } public abstract class SystemBase : SystemBase { public List Objects { get; set; } /// /// 对所有Objects并行循环执行Do /// protected abstract bool ParallelDo { get; } public SystemBase() { Objects = Create();//.Select(v=>Activator.CreateInstance(typeof(T),v)).OfType().ToList(); } public override void Update(List list) { if (ParallelDo) { Parallel.ForEach(Objects, new ParallelOptions { MaxDegreeOfParallelism = 256 }, obj => { var sw = new Stopwatch(); sw.Start(); InvokeDo(obj); sw.Stop(); list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds }); }); } else { foreach (var obj in Objects) { var sw = new Stopwatch(); sw.Start(); InvokeDo(obj); sw.Stop(); list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds }); } } } private void InvokeDo(T obj) { var channel = new Channel { World = World.Description, Stage = "DoLogics", System = Description, Item = obj.ToString() }; try { if (channel.Item == "1") { var a = 1; } Ltc.SetChannel(channel); World.OnInternalLog(channel, "开始"); Do(obj); } catch (Exception ex) { World.OnError(channel, ex); } finally { World.OnInternalLog(channel, "结束"); World.Publish(); } } public abstract List Create(); public abstract void Do(T obj); public override List GetObjects() { return Objects.OfType().ToList(); } } public abstract class DeviceSystem : SystemBase where T : EntityEx { public override List Create() { var t = typeof(T); while (true) { if (t.IsGenericType) break; t = t.BaseType; } if (t == typeof(EntityEx)) { var list = Device.All .Where(Select) .Select(v => Activator.CreateInstance(typeof(T), v)).OfType().ToList();//此时才实例化Protocol return list; } else { var types = t.GetGenericArguments(); var list = Device.All.Where(v => types.All(v.HasProtocol)) .Where(Select) .Select(v => Activator.CreateInstance(typeof(T), v, World)).OfType().ToList();//此时才实例化Protocol if (list.Count == 0) { //throw new Exception($"{this.GetType().Name}未匹配到任何Device"); } return list; } } /// /// 筛选出需要实例化Protocol的Device /// /// /// public abstract bool Select(Device dev); //public abstract List CreateDevices(); } public abstract class ServiceSystem : SystemBase { private ConcurrentQueue>> Actions = new ConcurrentQueue>>(); public TR Invoke(T obj) { var flag = false; TR result = default(TR); Actions.Enqueue(list => { var sw = new Stopwatch(); sw.Start(); try { result = InvokeDo(obj); } finally { sw.Stop(); list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds }); flag = true; } }); SpinWait.SpinUntil(() => flag); return result; } protected abstract TR Do(T obj); public override List GetObjects() { return new List(); } public override void Update(List list) { while (Actions.TryDequeue(out var act)) { act(list); } } private TR InvokeDo(T obj) { var channel = new Channel { World = World.Description, Stage = "DoLogics", System = Description, Item = obj.ToString() }; try { Ltc.SetChannel(channel); World.OnInternalLog(channel, "开始"); return Do(obj); } catch (Exception ex) { throw; } finally { World.OnInternalLog(channel, "结束"); World.Publish(); } } } public abstract class ServiceSystem : SystemBase { private ConcurrentQueue>> Actions = new ConcurrentQueue>>(); public void Invoke(T obj) { Actions.Enqueue(list => { var sw = new Stopwatch(); sw.Start(); try { InvokeDo(obj); } finally { sw.Stop(); list.AddSafe(new WorkTimes { Key = $"{obj?.ToString()}", Total = sw.ElapsedMilliseconds }); } }); } protected abstract void Do(T obj); private void InvokeDo(T obj) { var channel = new Channel { World = World.Description, Stage = "DoLogics", System = Description, Item = obj.ToString() }; try { Ltc.SetChannel(channel); World.OnInternalLog(channel, "开始"); Do(obj); } catch (Exception ex) { throw; } finally { World.OnInternalLog(channel, "结束"); World.Publish(); } } public override List GetObjects() { return new List(); } public override void Update(List list) { while (Actions.TryDequeue(out var act)) { act(list); } } } }