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; namespace HBLConsole.Service { /// /// 线程管理 /// public class ThreadOperate { private volatile static ThreadOperate _Instance; public static ThreadOperate GetInstance => _Instance ?? (_Instance = new ThreadOperate()); private ThreadOperate() { } string guid = "871d7e28-c413-4675-8d28-64e4dca4c2d3-"; ConcurrentDictionary Threads = new ConcurrentDictionary(); ConcurrentDictionary CancellationTokenSources = new ConcurrentDictionary(); /// /// 停止指定任务 /// /// 任务名 /// 任务结束的回调 public void StopTask(string taskName, Action ExitCallback = null) { if (CancellationTokenSources.ContainsKey(guid + taskName)) CancellationTokenSources[guid + taskName]?.Cancel(); ActionOperate.GetInstance.Register(ExitCallback, guid + taskName); } /// /// 长任务,带 while true 的循环 /// /// /// public void StartLong(Action action, string TaskName, Action RunComplete = null) { CancellationTokenSources.TryAdd(guid + TaskName, new CancellationTokenSource()); bool result = Threads.TryAdd(guid + TaskName, Task.Factory.StartNew(new Action(() => { try { while (!CancellationTokenSources[guid + TaskName].IsCancellationRequested) { if (action != null) action(); } } catch (Exception ex) { MessageLog.GetInstance.Show($"线程 【{TaskName}】运行发生异常,已重启"); CancellationTokenSources.TryRemove(guid + TaskName, out CancellationTokenSource temp); Threads.TryRemove(guid + TaskName, out Task temp1); } }), CancellationTokenSources[guid + TaskName].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); if (RunComplete != null) RunComplete(); }), guid + TaskName)); MessageLog.GetInstance.Show($"启动线程 【{TaskName}】"); if (!result) MessageLog.GetInstance.Show($"【{TaskName}】任务已存在,请检查 TaskName"); } /// /// 不带 while true 的循环任务 /// /// /// public void Start(Action action, string TaskName) { CancellationTokenSources.TryAdd(guid + TaskName, new CancellationTokenSource()); bool result = Threads.TryAdd(guid + TaskName, Task.Factory.StartNew(new Action(() => { action(); }), CancellationTokenSources[guid + TaskName].Token).ContinueWith(new Action((t, o) => { ThreadStatus(t, o.ToString()); }), guid + TaskName)); if (!result) MessageLog.GetInstance.Show($"【{TaskName}】任务已存在,请检查 TaskName"); } private void ThreadStatus(Task task, string TaskName) { bool IsRemove = false; string name = TaskName.Substring(TaskName.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(TaskName)) Threads.TryRemove(Threads.FirstOrDefault(p => p.Key == TaskName)); if (CancellationTokenSources.ContainsKey(TaskName)) CancellationTokenSources.TryRemove(CancellationTokenSources.FirstOrDefault(p => p.Key == TaskName)); ActionOperate.GetInstance.Send(TaskName); } } /// /// 释放所有线程资源 /// public void Dispose() { for (int i = 0; i < CancellationTokenSources.Count; i++) { CancellationTokenSources.ElementAt(i).Value.Cancel(); } } /// /// 判断指定线程是否完成 /// /// /// public bool IsComplete(string TaskName) { if (Threads.ContainsKey(guid + TaskName)) { return Threads[guid + TaskName].IsCompleted; } else { return false; } } } }