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;
}
}
}