using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; using BPASmartClient.Message; namespace BPASmartClient.Helper { /// /// 线程管理 /// 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) { MessageLog.GetInstance.ShowEx(ex.ToString()); if (IsRestart) { Thread.Sleep(2000); MessageLog.GetInstance.Show($"线程 【{key}】运行发生异常,已重启"); goto ReStart; } else { CancellationTokenSources.TryRemove(guid + key, out CancellationTokenSource temp); Threads.TryRemove(guid + key, out Task temp1); MessageLog.GetInstance.Show($"线程 【{key}】运行发生异常,已退出"); } } }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); if (RunComplete != null) RunComplete(); }), guid + key)); MessageLog.GetInstance.Show($"启动线程 【{key}】"); if (!result) MessageLog.GetInstance.Show($"【{key}】任务已存在,请检查 TaskName"); } /// /// 不带 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) { MessageLog.GetInstance.ShowEx(ex.ToString()); if (isRestart) { MessageLog.GetInstance.Show($"线程 【{key}】正在重启"); CancellationTokenSources.TryRemove(guid + key, out CancellationTokenSource item1); Threads.TryRemove(guid + key, out Task item2); Start(action, key, isRestart); } else { MessageLog.GetInstance.Show($"线程 【{key}】运行发生异常"); } } }), CancellationTokenSources[guid + key].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); }), guid + key)); MessageLog.GetInstance.Show($"启动线程 【{key}】"); if (!result) MessageLog.GetInstance.Show($"【{key}】任务已存在,请检查 TaskName"); } private void ThreadStatus(Task task, string key) { bool IsRemove = false; string name = key.Substring(key.LastIndexOf('-') + 1); switch (task.Status) { case TaskStatus.RanToCompletion: MessageLog.GetInstance.Show($"线程【{name}】执行完成"); IsRemove = true; break; case TaskStatus.Faulted: MessageLog.GetInstance.Show($"线程【{name}】执行异常,{task.Exception}"); IsRemove = true; break; case TaskStatus.Canceled: MessageLog.GetInstance.Show($"线程【{name}】已取消"); IsRemove = true; break; default: break; } if (IsRemove) { if (Threads.ContainsKey(key)) Threads.TryRemove(key, out Task t); //Threads.TryRemove(Threads.FirstOrDefault(p => p.Key == TaskName)); if (CancellationTokenSources.ContainsKey(key)) CancellationTokenSources.TryRemove(key, out CancellationTokenSource cts); //CancellationTokenSources.TryRemove(CancellationTokenSources.FirstOrDefault(p => p.Key == TaskName)); //keys.Remove(key); //if (keys != null && keys.Count == 0) ActionManage.GetInstance.Send(callbackKey.ToString()); 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; } } }