diff --git a/HKCardOUT/Helper/DataBus.cs b/HKCardOUT/Helper/DataBus.cs index f5a618d..be24fe1 100644 --- a/HKCardOUT/Helper/DataBus.cs +++ b/HKCardOUT/Helper/DataBus.cs @@ -20,6 +20,7 @@ namespace HKCardOUT.Helper _ConnectionString = SyncStatic.CreateFile(Path.Combine(SyncStatic.CreateDir(Route), value)); } } + public static bool NetWordState { get; set; } = false; public static string Cron { get; set; } public static string SaasRoute { get; set; } } diff --git a/HKCardOUT/Helper/HKHelper.cs b/HKCardOUT/Helper/HKHelper.cs new file mode 100644 index 0000000..0119f9b --- /dev/null +++ b/HKCardOUT/Helper/HKHelper.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace HKCardOut.Helper +{ + public class HKHelper: Singleton + { + /// + /// 判断网络状况的方法,返回值true为连接,false为未连接 + /// + /// + /// + /// + [DllImport("wininet")] + public extern static bool InternetGetConnectedState(out int conState, int reder); + /// + /// 获取当前网络连接状态 + /// + /// 成功连接网络返回 true,未连接返回 false + public bool GetNetworkState() + { + return InternetGetConnectedState(out int i, 0); + } + + } + } diff --git a/HKCardOUT/Helper/ThreadManage.cs b/HKCardOUT/Helper/ThreadManage.cs new file mode 100644 index 0000000..4c89684 --- /dev/null +++ b/HKCardOUT/Helper/ThreadManage.cs @@ -0,0 +1,445 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace HKCardOut.Helper +{ + 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; + } + } +} diff --git a/HKCardOUT/ViewModels/RootViewModel.cs b/HKCardOUT/ViewModels/RootViewModel.cs index 4275251..d40857b 100644 --- a/HKCardOUT/ViewModels/RootViewModel.cs +++ b/HKCardOUT/ViewModels/RootViewModel.cs @@ -1,19 +1,42 @@ -using Stylet; +using HKCardOut.Helper; +using HKCardOUT.Helper; +using Stylet; +using System; +using System.Threading; namespace HKCardOUT.ViewModels { public class RootViewModel : PropertyChangedBase { - private string _title = "HandyControl Application"; - public string Title - { - get { return _title; } - set { SetAndNotify(ref _title, value); } - } public RootViewModel() { + MainThread(); + } + #region 方法 + private void MainThread() + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + try + { + //1.检测网络上下线 + bool network = HKHelper.GetInstance().GetNetworkState(); + if (network != DataBus.NetWordState) + { + if (network) HandyControl.Controls.Growl.InfoGlobal("网络连接成功"); + else HandyControl.Controls.Growl.InfoGlobal("系统已离线,请连接网络!!!"); + DataBus.NetWordState = network; + } + Thread.Sleep(3000); + } + catch (Exception ex) + { + HandyControl.Controls.Growl.InfoGlobal(ex.Message); + } + }), "循环状态监测线程", false); } + #endregion } }