|
- 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
- {
- /// <summary>
- /// 线程管理
- /// </summary>
- 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<string, Task> Threads = new ConcurrentDictionary<string, Task>();
- ConcurrentDictionary<string, CancellationTokenSource> CancellationTokenSources = new ConcurrentDictionary<string, CancellationTokenSource>();
-
- /// <summary>
- /// 停止指定任务
- /// </summary>
- /// <param name="taskName">任务名</param>
- /// <param name="ExitCallback">任务结束的回调</param>
- public void StopTask(string taskName, Action ExitCallback = null)
- {
- if (CancellationTokenSources.ContainsKey(guid + taskName))
- CancellationTokenSources[guid + taskName]?.Cancel();
- ActionOperate.GetInstance.Register(ExitCallback, guid + taskName);
- }
-
- /// <summary>
- /// 长任务,带 while true 的循环
- /// </summary>
- /// <param name="action"></param>
- /// <param name="TaskName"></param>
- 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<Task, object>((t, o) =>
- {
- ThreadStatus(t, o.ToString());
- if (RunComplete != null) RunComplete();
- }), guid + TaskName));
- MessageLog.GetInstance.Show($"启动线程 【{TaskName}】");
- if (!result) MessageLog.GetInstance.Show($"【{TaskName}】任务已存在,请检查 TaskName");
-
- }
-
-
- /// <summary>
- /// 不带 while true 的循环任务
- /// </summary>
- /// <param name="action"></param>
- /// <param name="TaskName"></param>
- 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<Task, object>((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);
- }
- }
-
- /// <summary>
- /// 释放所有线程资源
- /// </summary>
- public void Dispose()
- {
- for (int i = 0; i < CancellationTokenSources.Count; i++)
- {
- CancellationTokenSources.ElementAt(i).Value.Cancel();
- }
- }
-
- /// <summary>
- /// 判断指定线程是否完成
- /// </summary>
- /// <param name="TaskName"></param>
- /// <returns></returns>
- public bool IsComplete(string TaskName)
- {
- if (Threads.ContainsKey(guid + TaskName))
- {
- return Threads[guid + TaskName].IsCompleted;
- }
- else
- {
- return false;
- }
- }
-
- }
-
- }
|