using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace HKHelper { public class Singleton where T : new() { private static object _async = new object(); private static T _instance; static readonly Lazy instance = new(); /// /// 获取实例 /// /// public static T GetInstance() { return instance.Value; } } public class ThreadManage : Singleton { string guid = "871d7e28-c413-4675-8d28-64e4dca4c2d3-"; private static readonly object _lock = new object(); StringBuilder callbackKey = new StringBuilder(); List keys = new List(); ConcurrentDictionary Threads = new ConcurrentDictionary(); ConcurrentDictionary CancellationTokenSources = new ConcurrentDictionary(); /// /// 停止指定任务 /// /// 任务名 /// 任务结束的回调 public void StopTask(string key, Action ExitCallback = null) { if (CancellationTokenSources.ContainsKey(guid + key)) { CancellationTokenSources[guid + key]?.Cancel(); ActionManage.GetInstance.Register(ExitCallback, guid + key); } else { if (ExitCallback != null) ExitCallback(); } } /// /// 长任务,带 while true 的循环 /// /// /// public void StartLong(Action action, string key, bool IsRestart = false, Action RunComplete = null) { CancellationTokenSources.TryAdd(guid + key, new CancellationTokenSource()); bool result = Threads.TryAdd(guid + key, Task.Factory.StartNew(new Action(() => { Thread.CurrentThread.Name = key; ReStart: try { while (!CancellationTokenSources[guid + key].IsCancellationRequested) { if (action != null) action(); } } catch (Exception ex) { if (IsRestart) { Thread.Sleep(2000); goto ReStart; } else { CancellationTokenSources.TryRemove(guid + key, out CancellationTokenSource temp); Threads.TryRemove(guid + key, out Task temp1); } } }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); if (RunComplete != null) RunComplete(); }), guid + key)); } /// /// 不带 while true 的循环任务 /// /// /// public void Start(Action action, string key, bool isRestart = false) { CancellationTokenSources.TryAdd(guid + key, new CancellationTokenSource()); bool result = Threads.TryAdd(guid + key, Task.Factory.StartNew(new Action(() => { Thread.CurrentThread.Name = key; try { if (action != null) action(); } catch (Exception ex) { if (isRestart) { CancellationTokenSources.TryRemove(guid + key, out CancellationTokenSource item1); Threads.TryRemove(guid + key, out Task item2); Start(action, key, isRestart); } else { } } }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); }), guid + key)); } private void ThreadStatus(Task task, string key) { bool IsRemove = false; string name = key.Substring(key.LastIndexOf('-') + 1); switch (task.Status) { case TaskStatus.RanToCompletion: IsRemove = true; break; case TaskStatus.Faulted: IsRemove = true; break; case TaskStatus.Canceled: IsRemove = true; break; default: break; } if (IsRemove) { if (Threads.ContainsKey(key)) Threads.TryRemove(key, out Task t); if (CancellationTokenSources.ContainsKey(key)) CancellationTokenSources.TryRemove(key, out CancellationTokenSource cts); ActionManage.GetInstance.Send(key); } } /// /// 释放所有线程资源 /// public void Dispose() { for (int i = 0; i < CancellationTokenSources.Count; i++) { CancellationTokenSources.ElementAt(i).Value.Cancel(); } } /// /// 判断指定线程是否完成 /// /// /// public bool IsComplete(string key) { if (Threads.ContainsKey(guid + key)) return Threads[guid + key].IsCompleted; return false; } } internal class Delegation { /// /// 带参数的委托 /// public Action ActionPar { get; set; } /// /// 带参数的委托 /// public Action ActionPars { get; set; } /// /// 无参数的委托 /// public Action ActionBus { get; set; } /// /// 有返回值的委托 /// public Func FuncObj { get; set; } /// /// 有返回值,有参数的委托 /// public Func FuncPar { get; set; } } public class ActionManage { private volatile static ActionManage _Instance; public static ActionManage GetInstance => _Instance ?? (_Instance = new ActionManage()); private ActionManage() { } //private static ConcurrentDictionary actions = new ConcurrentDictionary(); private static ConcurrentDictionary actions = new ConcurrentDictionary(); static readonly object SendLock = new object(); static readonly object SendParLock = new object(); static readonly object RegisterLock = new object(); /// /// 注销委托 /// /// public void CancelRegister(string key) { if (actions.ContainsKey(key)) actions.TryRemove(key, out Delegation t); } /// /// 执行注册过的委托 /// /// 注册委托的key /// 委托参数 /// 委托回调 public void Send(string key, object par, Action Callback = null) { lock (SendLock) if (actions.ContainsKey(key)) actions[key].ActionPar.Invoke(par, Callback); } /// /// 执行注册过的委托 /// /// 注册委托的key /// 委托参数 /// 委托回调 public void Send(string key, object[] par, Action Callback = null) { lock (SendLock) if (actions.ContainsKey(key)) actions[key].ActionPars.Invokes(par, Callback); } /// /// 执行注册过的委托 /// /// 注册委托的key /// 委托回调 public void Send(string key, Action Callback = null) { lock (SendLock) if (actions.ContainsKey(key)) actions[key].ActionBus?.Invoke(Callback); } public object SendResult(string key, object par = null) { lock (SendLock) if (actions.ContainsKey(key)) if (par == null) { return actions[key].FuncObj?.Invoke(); } else { return actions[key].FuncPar?.Invoke(par); } return default; } public void Register(T action, string key) { lock (RegisterLock) { if (action != null) { if (!actions.ContainsKey(key)) { if (action is Action actionBus) actions.TryAdd(key, new Delegation() { ActionBus = actionBus }); if (action is Action actionObj) actions.TryAdd(key, new Delegation() { ActionPar = actionObj }); if (action is Action actionObjs) actions.TryAdd(key, new Delegation() { ActionPars = actionObjs }); if (action is Func funcObj) actions.TryAdd(key, new Delegation() { FuncObj = funcObj }); if (action is Func puncPar) actions.TryAdd(key, new Delegation() { FuncPar = puncPar }); } } } } } public static class ExpandMethod { /// /// 获取布尔数组指定值得索引 /// /// 要获取索引的数组 /// 要获取索引的值 /// public static int GetIndex(this bool[] obj, bool value) { if (obj == null) return -1; return Array.FindIndex(obj, p => p == value); } /// /// 获取字符串数组指定值得索引 /// /// 要获取索引的数组 /// 要获取索引的值 /// public static int GetIndex(this string[] obj, string value) { if (obj == null || value == null) return -1; return Array.FindIndex(obj, p => p == value && p.Length > 0); } /// /// 委托回调 /// /// 要执行的委托 /// 委托回调 public static void Invoke(this Action action, Action callback) { action?.Invoke(); callback?.Invoke(); } /// /// 委托回调 /// /// 要执行的委托 /// 要执行的委托的参数 /// 委托回调 public static void Invoke(this Action action, object par, Action callback) { action?.Invoke(par); callback?.Invoke(); } public static void Invokes(this Action action, object[] par, Action callback) { action?.Invoke(par); callback?.Invoke(); } /// /// 字节数组转换成32位整数 /// /// /// public static int BytesToInt(this byte[] bytes) { if (bytes.Length > 4) return -1; int ReturnVlaue = 0; for (int i = 0; i < bytes.Length; i++) { ReturnVlaue += (int)(bytes[i] << (i * 8)); } return ReturnVlaue; } /// /// 字节数组转换成 ushort 数组 /// /// 要转换的字节数组 /// 字节高度顺序控制 /// public static ushort[] BytesToUshorts(this byte[] bytes, bool reverse = false) { int len = bytes.Length; byte[] srcPlus = new byte[len + 1]; bytes.CopyTo(srcPlus, 0); int count = len >> 1; if (len % 2 != 0) { count += 1; } ushort[] dest = new ushort[count]; if (reverse) { for (int i = 0; i < count; i++) { dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff); } } else { for (int i = 0; i < count; i++) { dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8); } } return dest; } /// /// ushort 数组转换成字节数组 /// /// 需要转换的 ushort数组 /// 高低字节的设置 /// public static byte[] UshortsToBytes(this ushort[] src, bool reverse = false) { int count = src.Length; byte[] dest = new byte[count << 1]; if (reverse) { for (int i = 0; i < count; i++) { dest[i * 2] = (byte)(src[i] >> 8); dest[i * 2 + 1] = (byte)(src[i] >> 0); } } else { for (int i = 0; i < count; i++) { dest[i * 2] = (byte)(src[i] >> 0); dest[i * 2 + 1] = (byte)(src[i] >> 8); } } return dest; } } }