| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 | using System.Collections.Concurrent;using System.Diagnostics;using System.Reflection;namespace WCS.Core;public abstract class SystemBase : DescriptionClass{    public SystemBase()    {        var attr = GetType().GetCustomAttribute<BelongToAttribute>();        if (attr == null) return;        var wt = attr.WorldType;        World = World.Worlds.First(v => v.GetType() == wt);    }    public World World { get; }    public abstract List<object> GetObjects();    public abstract void Update(List<WorkTimes> list);}public abstract class SystemBase<T> : SystemBase{    public SystemBase()    {        Objects = Create(); //.Select(v=>Activator.CreateInstance(typeof(T),v)).OfType<T>().ToList();    }    public List<T> Objects { get; set; }    /// <summary>    ///     对所有Objects并行循环执行Do    /// </summary>    protected abstract bool ParallelDo { get; }    public override void Update(List<WorkTimes> 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<T> Create();    public abstract void Do(T obj);    public override List<object> GetObjects()    {        return Objects.OfType<object>().ToList();    }}public abstract class DeviceSystem<T> : SystemBase<T> where T : EntityEx<Device>{    public override List<T> Create()    {        var t = typeof(T);        while (true)        {            if (t.IsGenericType) break;            t = t.BaseType;        }        if (t == typeof(EntityEx<Device>))        {            var list = Device.All                .Where(Select)                .Select(v => Activator.CreateInstance(typeof(T), v)).OfType<T>().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<T>().ToList(); //此时才实例化Protocol            if (list.Count == 0)            {                //throw new Exception($"{this.GetType().Name}未匹配到任何Device");            }            return list;        }    }    /// <summary>    ///     筛选出需要实例化Protocol的Device    /// </summary>    /// <param name="dev"></param>    /// <returns></returns>    public abstract bool Select(Device dev);    //public abstract List<Device> CreateDevices();}public abstract class ServiceSystem<T, TR> : SystemBase{    private readonly ConcurrentQueue<Action<List<WorkTimes>>> Actions = new();    public TR Invoke(T obj)    {        var flag = false;        var 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<object> GetObjects()    {        return new List<object>();    }    public override void Update(List<WorkTimes> 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);        }        finally        {            World.OnInternalLog(channel, "结束");            World.Publish();        }    }}public abstract class ServiceSystem<T> : SystemBase{    private readonly ConcurrentQueue<Action<List<WorkTimes>>> Actions = new();    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);        }        finally        {            World.OnInternalLog(channel, "结束");            World.Publish();        }    }    public override List<object> GetObjects()    {        return new List<object>();    }    public override void Update(List<WorkTimes> list)    {        while (Actions.TryDequeue(out var act)) act(list);    }}
 |