123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Threading;
- using System.Threading.Tasks;
- using WCS.Entity;
- namespace WCS.Core
- {
- public abstract class LogicHandler
- {
- protected bool Stoped = false;
- protected string Description { get; private set; }
- public static List<object> AllObjects = new List<object>();
- private static List<LogicHandler> Handlers = new List<LogicHandler>();
- public static Action<string, string, string> DbLog;
- public LogicHandler()
- {
- var attr = this.GetType().GetCustomAttributes(false).OfType<DescriptionAttribute>().FirstOrDefault();
- if (attr != null)
- Description = attr.Description;
- else
- Description = this.GetType().Name;
- }
- public abstract void Start();
- public virtual bool ParallelRun
- {
- get
- {
- return false;
- }
- }
- /// <summary>
- /// 数据刷新时触发
- /// </summary>
- /// <param name="milliseconds">离上次触发的间隔时间(毫秒)</param>
- public abstract void Update(double milliseconds);
- public void Stop()
- {
- Stoped = true;
- }
- public static void AddManager(LogicHandler handler)
- {
- Handlers.Add(handler);
- }
- public static void StartAll()
- {
- foreach (var h in Handlers)
- {
- h.Start();
- }
- var th = new Thread(new ThreadStart(Loop));
- th.IsBackground = true;
- th.Start();
- }
- private static DateTime last = DateTime.Now;
- private static DateTime last2 = DateTime.Now;
- private static int logicTimes;
- public static DateTime Frame { get; private set; }
- private static void Loop()
- {
- var arr = AllObjects.OfType<WCS_DEVICE>().Where(v => v.ENABLED).SelectMany(v => v.PROTOCOLS)
- .Where(v => v.ENABLED && v.DB.ENABLED && v.DB.PLC.ENABLED)
- .GroupBy(v => v.DB).Select(v => v.Key)
- .ToArray();
- while (true)
- {
- var dd = DateTime.Now;
- Frame = DateTime.Now;
- Parallel.ForEach<WCS_DATABLOCK>(arr, db =>
- {
- try
- {
- Ltc.SetChannel("刷新");
- db.Ex().DataRefresh();
- }
- catch (Exception ex)
- {
- Console.WriteLine("更新" + db.NAME + "数据失败:" + ex.Message);
- }
- });
- var dbTimes = (DateTime.Now - dd).TotalMilliseconds;
- // Console.WriteLine("----------"+dd2);
- var total = (DateTime.Now - last).TotalMilliseconds;
- var s = (int)(600 - total);
- if (s > 0)
- Thread.Sleep(s);
- total = (DateTime.Now - last).TotalMilliseconds;
- Console.ForegroundColor = ConsoleColor.Blue;
- Console.WriteLine("------刷新DB块数据耗时:" + ((int)dbTimes).ToString().PadRight(4, ' ') + ";业务逻辑耗时:" + ((int)logicTimes).ToString().PadRight(4, ' ') + ";周期总耗时" + ((int)total).ToString().PadRight(4, ' ') + "");
- Console.ResetColor();
- last = DateTime.Now;
- //Configs.DoCmds(cmd =>
- //{
- // try
- // {
- // if (!cmd.ENABLED)
- // return;
- // var obj = Device.Find(cmd.DEVICE_CODE).PROTOCOLS.Where(v => v.DB.PROTOCOL == cmd.PROTOCOL).FirstOrDefault();
- // //var obj = AllObjects.OfType<WCS_DEVICEPROTOCOL>().Where(v => v.DB.PROTOCOL == cmd.PROTOCOL && v.DEVICE.CODE == cmd.DEVICE_CODE).FirstOrDefault();
- // if (obj != null)
- // {
- // var proxy = obj.Data() as ProtocolProxyBase;
- // if (proxy.WCSVersion != cmd.WCSVERSION && cmd.WCSVERSION >= 0)
- // {
- // throw new Exception("WCS数据已变更,无法执行CMD。ID:" + cmd.ID);
- // }
- // var prop = proxy.GetType().GetProperty(cmd.PROPERTY);
- // if (prop.PropertyType.IsEnum)
- // {
- // var value = Enum.Parse(prop.PropertyType, cmd.VALUE);
- // proxy.Update(cmd.PROPERTY, value, cmd.UPDATEUSER);
- // }
- // else
- // {
- // var value = Convert.ChangeType(cmd.VALUE, prop.PropertyType);
- // proxy.Update(cmd.PROPERTY, value, cmd.UPDATEUSER);
- // }
- // }
- // }
- // catch (Exception ex)
- // {
- // Console.WriteLine(ex.Message);
- // }
- //});
- Parallel.ForEach<LogicHandler>(Handlers, m =>
- {
- var dm = DateTime.Now;
- try
- {
- m.Update(total);
- }
- catch (Exception ex)
- {
- //Console.WriteLine(ex.GetBaseException().Message);
- }
- var dm2 = (DateTime.Now - dm).TotalMilliseconds;
- //Console.WriteLine(m.GetType().Name + ":" + dm2);
- });
- //foreach (var m in Handlers)
- //{
- // var dm = DateTime.Now;
- // try
- // {
- // m.Update(total);
- // }
- // catch (Exception ex)
- // {
- // //Console.WriteLine(ex.GetBaseException().Message);
- // }
- // var dm2 = (DateTime.Now - dm).TotalMilliseconds;
- //}
- Configs.Publish();
- logicTimes = (int)(DateTime.Now - last).TotalMilliseconds;
- }
- }
- public static void StopAll()
- {
- foreach (var h in Handlers)
- {
- try
- {
- h.Stop();
- }
- catch { }
- }
- }
- }
- public abstract class LogicHandler<T> : LogicHandler where T : EntityEx<WCS_DEVICE>
- {
- private string logPath = "";
- protected List<WorkInfo<T>> Works = new List<WorkInfo<T>>();
- private IEnumerable<T> _Objects = null;
- protected IEnumerable<T> Objects
- {
- get
- {
- if (_Objects == null)
- {
- _Objects = AllObjects.OfType<WCS_DEVICE>().Where(v => SelectDevice(v)).Select(v => Activator.CreateInstance(typeof(T), v)).OfType<T>().ToArray();
- }
- return _Objects.Where(v => v.Entity.ENABLED && v.Entity.PROTOCOLS.All(d => d.ENABLED && d.DB.ENABLED && d.DB.PLC.ENABLED));
- }
- }
- private bool SelectDevice(WCS_DEVICE dev)
- {
- var typenames = typeof(T).GenericTypeArguments.Select(v => v.AssemblyQualifiedName).ToArray();
- var res = typenames.All(v => dev.PROTOCOLS.Any(d => d.DB.PROTOCOL == v));
- return res;
- }
- public LogicHandler()
- {
- logPath = @"D:\WCSLog\Log\" + this.Description + @"\";
- }
- public void AddWork(Func<T, bool> condition, Action<T> work, bool parallel = false)
- {
- var title = work.Method.Name;
- var attr = work.Method.GetCustomAttributes(false).OfType<DescriptionAttribute>().FirstOrDefault();
- if (attr != null)
- title = attr.Description;
- var arr = Objects.Where(condition).ToArray();
- this.Works.Add(new WorkInfo<T> { Work = work, Params = arr, Title = title, Parallel = parallel });
- }
- public void AddWork(IEnumerable<T> arr, Action<T> work, bool parallel = false)
- {
- var title = work.Method.Name;
- var attr = work.Method.GetCustomAttributes(false).OfType<DescriptionAttribute>().FirstOrDefault();
- if (attr != null)
- title = attr.Description;
- this.Works.Add(new WorkInfo<T> { Work = work, Params = arr, Title = title, Parallel = parallel });
- }
- public override void Update(double milliseconds)
- {
- if (ParallelRun)
- {
- Parallel.ForEach(Works, w =>
- {
- DoWork(w);
- });
- }
- else
- {
- foreach (var w in Works)
- {
- DoWork(w);
- }
- }
- }
- protected virtual void DoWork(WorkInfo<T> work)
- {
- if (work.Parallel)
- {
- Parallel.ForEach(work.Params, p =>
- {
- Do(work, p);
- });
- }
- else
- {
- foreach (var p in work.Params)
- {
- Do(work, p);
- }
- }
- }
- protected virtual void Do(WorkInfo<T> wi, T p)
- {
- var channel = Description + "." + wi.Title + "." + p.ToString();
- try
- {
- Ltc.SetChannel(channel);
- Ltc.Log("开始---------------------------------------");
- wi.Work(p);
- }
- catch (Exception ex)
- {
- Ltc.Log(ex.GetBaseException().Message);
- Log(wi, p, ex);
- }
- finally
- {
- Ltc.Log("结束\n");
- }
- }
- protected virtual void Log(WorkInfo<T> wi, T p, Exception ex)
- {
- try
- {
- var msg = Description + "--" + wi.Title + "--";
- if (p is IProtocol)
- {
- msg += (p as IProtocol).PROTOCOL().DEVICE.CODE;
- }
- var con = ex.GetBaseException().Message.Split("|");
- msg = msg + ":" + con[0];
- //Console.WriteLine(msg);
- DbLog.Invoke(msg, con[1], con[2]);
- }
- catch (Exception ex2)
- {
- }
- }
- private static object lockobj = new object();
- protected void Log(string msg)
- {
- lock (lockobj)
- {
- try
- {
- var str = "-----------" + DateTime.Now.ToString("yyyyMMdd HH:mm:ss:fff") + "-----------\r\n";
- str += msg;
- if (!Directory.Exists(logPath))
- Directory.CreateDirectory(logPath);
- var file = logPath + DateTime.Now.ToString("yyyyMMdd") + ".log";
- var writer = File.AppendText(file);
- writer.WriteLine(str);
- writer.Flush();
- writer.Close();
- }
- catch (Exception ex)
- {
- }
- }
- }
- /// <summary>
- /// 此方法不会被自动调用,请在Start方法中使用AddWork将其添加至工作队列
- /// </summary>
- /// <param name="dev"></param>
- [Description("执行")]
- protected abstract void Execute(T dev);
- }
- public abstract class WorkHandler : LogicHandler
- {
- private string logPath = "";
- protected List<WorkInfo> Works = new List<WorkInfo>();
- public WorkHandler()
- {
- logPath = @"Log\" + this.Description + @"\";
- var arr = Assembly.GetEntryAssembly().GetTypes().Where(v => v.IsSubclassOf(typeof(Work))).Where(v =>
- {
- var attr = v.GetCustomAttribute<WorkTitleAttribute>();
- if (attr == null)
- return false;
- return attr.Handler == this.GetType();
- });
- var works = arr.Select(v => Activator.CreateInstance(v) as Work).Select(v =>
- {
- var attr = v.GetType().GetCustomAttribute<WorkTitleAttribute>();
- return new WorkInfo { Params = v.GetObjs(), Work = v.Execute, Title = attr.Title, Parallel = attr.Parallel };
- }).ToArray();
- Works.AddRange(works);
- }
- public override sealed void Start()
- {
- //throw new NotImplementedException();
- }
- public override void Update(double milliseconds)
- {
- if (ParallelRun)
- {
- Parallel.ForEach(Works, w =>
- {
- DoWork(w);
- });
- }
- else
- {
- foreach (var w in Works)
- {
- DoWork(w);
- }
- }
- }
- protected virtual void DoWork(WorkInfo work)
- {
- if (work.Parallel)
- {
- Parallel.ForEach(work.Params, p =>
- {
- Do(work, p);
- });
- }
- else
- {
- foreach (var p in work.Params)
- {
- Do(work, p);
- }
- }
- }
- protected virtual void Do(WorkInfo wi, object p)
- {
- var dt = DateTime.Now;
- var channel = Description + "." + wi.Title + "." + p.ToString();
- try
- {
- Ltc.SetChannel(channel);
- Ltc.Log("开始---------------------------------------");
- wi.Work(p);
- }
- catch (Exception ex)
- {
- Ltc.Log(ex.GetBaseException().Message);
- Log(wi, p, ex);
- Configs.UploadException?.Invoke(p.ToString(), ex.GetBaseException().Message);
- }
- finally
- {
- var dd = (DateTime.Now - dt).TotalMilliseconds;
- if (dd > 500)
- {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine(channel + "耗时" + dd);
- Console.ResetColor();
- }
- if (dd > 10000)
- Configs.UploadException?.Invoke(p.ToString(), wi.Title + "执行耗时" + Math.Floor(dd / 1000) + "秒");
- Ltc.Log("结束\n");
- }
- }
- protected virtual void Log(WorkInfo wi, object p, Exception ex)
- {
- try
- {
- var msg = Description + "--" + wi.Title + "--";
- if (p is IProtocol)
- {
- msg += (p as IProtocol).PROTOCOL().DEVICE.CODE;
- }
- var con = ex.GetBaseException().Message.Split("|");
- msg = msg + ":" + con[0];
- //Console.WriteLine(msg);
- DbLog.Invoke(msg, con[1], con[2]);
- }
- catch (Exception ex2)
- {
- }
- }
- private static object lockobj = new object();
- protected void Log(string msg)
- {
- lock (lockobj)
- {
- try
- {
- var str = "-----------" + DateTime.Now.ToString("yyyyMMdd HH:mm:ss:fff") + "-----------\r\n";
- str += msg;
- if (!Directory.Exists(logPath))
- Directory.CreateDirectory(logPath);
- var file = logPath + DateTime.Now.ToString("yyyyMMdd") + ".log";
- var writer = File.AppendText(file);
- writer.WriteLine(str);
- writer.Flush();
- writer.Close();
- }
- catch (Exception ex)
- {
- }
- }
- }
- }
- public class WorkTitleAttribute : Attribute
- {
- public Type Handler { get; set; }
- public string Title { get; set; }
- public bool Parallel { get; set; }
- public WorkTitleAttribute(Type handler, string title, bool parallel = false)
- {
- this.Handler = handler;
- this.Title = title;
- this.Parallel = parallel;
- }
- }
- public abstract class Work
- {
- public abstract IEnumerable<Object> GetObjs();
- public abstract void Execute(object obj);
- }
- public abstract class Work<T> : Work
- {
- public override sealed void Execute(object obj)
- {
- Do((T)obj);
- }
- public override sealed IEnumerable<object> GetObjs()
- {
- return InitObjects().OfType<object>().ToArray();
- }
- protected abstract void Do(T obj);
- protected abstract bool SelectDevice(WCS_DEVICE dev);
- protected virtual IEnumerable<T> InitObjects()
- {
- var arr = Device.Where(v => v.ENABLED)
- .Where(v => SelectDevice(v)).ToArray();
- var res = arr.Select(v => (T)Activator.CreateInstance(typeof(T), v));
- return res;
- }
- }
- public abstract class DeviceWork<T> : Work<T> where T : EntityEx<WCS_DEVICE>
- {
- private string[] typenames;
- public DeviceWork()
- {
- typenames = typeof(T).GenericTypeArguments.Select(v => v.AssemblyQualifiedName).ToArray();
- }
- protected abstract override void Do(T obj);
- protected override sealed IEnumerable<T> InitObjects()
- {
- var arr = Device.Where(v => v.ENABLED && v.PROTOCOLS.All(d => d.ENABLED && d.DB.ENABLED && d.DB.PLC.ENABLED))
- .Where(v => typenames.All(d => v.PROTOCOLS.Any(e => e.DB.PROTOCOL == d)))
- .Where(v => SelectDevice(v)).ToArray();
- var res = arr.Select(v => Activator.CreateInstance(typeof(T), v) as T);
- return res;
- }
- }
- }
|