一、TaskL类型简介
二、目的:封装Task类、调用方便可控
三、实现过程
1、定义接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace HebianGu.ComLibModule.TaskEx
{
/// <summary> 执行任务类型的接口 </summary>
public interface IWorkInterface
{
/// <summary> 工作函数 </summary>
int RunWork(CancellationToken pToken);
}
/// <summary> 任务管理器 </summary>
public interface ITaskList : IWorkInterface
{
/// <summary> 当前任务 </summary>
Task<int> TaskCore
{
get;
set;
}
/// <summary> 上级任务 </summary>
Task<int> ParentTaskCore
{
get;
set;
}
/// <summary> 全局任务控制 </summary>
CancellationTokenSource Cts
{
get;
set;
}
}
/// <summary> 包含:开始时间,结束事件,用时,运行状态,暂停,文件路径,文件名等状态 </summary>
public class BaseTaskCore : ITaskList
{
bool isPause;
/// <summary> 是否暂停状态 </summary>
public bool IsPause
{
get { return isPause; }
set { isPause = value; }
}
bool isRestart = false;
/// <summary> 暂停继续后是否重新计算 </summary>
public bool IsRestart
{
get { return isRestart; }
set { isRestart = value; }
}
/// <summary> 抽象方法,提供子类扩展 </summary>
public virtual int RunCaseTaskWork(System.Threading.CancellationToken pToken)
{
//Process p = new Process();
//p.RunExe("DemoConsoleExe.exe", "");
return 0;
}
public int RunWork(System.Threading.CancellationToken pToken)
{
while (TaskControlModel.Instance.IsPause)
{
// 设置暂停状态
if (!isPause)
{
isPause = TaskControlModel.Instance.IsPause;
}
}
startTime = DateTime.Now;
isPause = TaskControlModel.Instance.IsPause;
RunCaseTaskWork(pToken);
// 如果是中间停止则重新计算
while (TaskControlModel.Instance.IsPause)
{
Thread.Sleep(1000);
// 设置暂停状态
if (!IsPause)
{
isPause = TaskControlModel.Instance.IsPause;
}
}
IsPause = TaskControlModel.Instance.IsPause;
if (isRestart)
{
isRestart = false;
RunWork(pToken);
}
endTime = DateTime.Now;
return 0;
}
DateTime startTime;
public DateTime StartTime
{
get { return startTime; }
set { startTime = value; }
}
DateTime endTime;
public DateTime EndTime
{
get { return endTime; }
set { endTime = value; }
}
/// <summary> 记录用时 </summary>
public string Time
{
get
{
if (endTime == default(DateTime))
{
if (startTime == default(DateTime))
{
string r = Regex.Replace(new TimeSpan().ToString(), @"\.\d+$", string.Empty);
TimeSpan ts = TimeSpan.Parse(r);
return ts.ToString();
}
else
{
string r = Regex.Replace((DateTime.Now - startTime).ToString(), @"\.\d+$", string.Empty);
TimeSpan ts = TimeSpan.Parse(r);
return ts.ToString();
}
}
else
{
string r = Regex.Replace((endTime - startTime).ToString(), @"\.\d+$", string.Empty);
TimeSpan ts = TimeSpan.Parse(r);
return ts.ToString();
}
}
}
Task<int> task;
public Task<int> TaskCore
{
get
{
return task;
}
set
{
task = value;
}
}
Task<int> pTask;
public Task<int> ParentTaskCore
{
get
{
return pTask;
}
set
{
pTask = value;
}
}
public string Id
{
get
{
return task.Id.ToString();
}
}
public string Pid
{
get
{
return pTask == null ? string.Empty : pTask.Id.ToString();
}
}
public bool IsCanceled
{
get
{
return task.IsCanceled;
}
}
public bool IsCompleted
{
get
{
return task.IsCompleted;
}
}
public bool IsFaulted
{
get
{
return task.IsFaulted;
}
}
public string Status
{
get
{
if (isPause)
{
return "暂停";
}
switch (task.Status)
{
case TaskStatus.Created:
return "准备";
case TaskStatus.WaitingForActivation:
return "等待";
case TaskStatus.WaitingToRun:
return "尚未开始执行";
case TaskStatus.Running:
return "运行";
case TaskStatus.WaitingForChildrenToComplete:
return "等待子任务";
case TaskStatus.RanToCompletion:
return "完成";
case TaskStatus.Canceled:
return "取消";
case TaskStatus.Faulted:
return "异常";
default:
return "";
}
}
}
CancellationTokenSource _cts;
public CancellationTokenSource Cts
{
get
{
return _cts;
}
set
{
_cts = value;
}
}
}
}
2、定义任务处理殷勤
注:BaseFactory<TaskListManager<T>>部分参考封装:实现单例、多例模式,业务层继承调用
using HebianGu.ComLibModule.Factory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace HebianGu.ComLibModule.TaskEx
{
/// <summary> 这是一个连续的任务,依次执行各个任务 </summary>
public class TaskListManager<T> : BaseFactory<TaskListManager<T>> where T : ITaskList
{
#region - Start 内部成员-
// 取消控制
CancellationTokenSource cts = null;
/// <summary> 是否已被取消 </summary>
public bool IsCancel
{
get
{
return cts.IsCancellationRequested;
}
}
LinkedList<T> taskList = null;
/// <summary> 任务的双向链表 </summary>
public LinkedList<T> TaskList
{
get { return taskList; }
set { taskList = value; }
}
/// <summary> 线程互斥 </summary>
private static object m_obj = new object();
T runTask;
/// <summary> 用于记录当前正在执行的任务 </summary>
public T RunTask
{
get { return runTask; }
set { runTask = value; }
}
/// <summary> 当切换进程时外部调用 </summary>
Action<Task<int>, T> _act;
/// <summary> 当切换进程时外部调用 </summary>
Func<Task<int>, int> _allOver;
/// <summary> 任务总数 </summary>
public int TotalCount
{
get { return this.taskList.Count; }
}
/// <summary> 完成的任务 </summary>
public List<T> CompleteTask
{
get { return this.taskList.ToList().FindAll(l => l.TaskCore.IsCompleted); }
}
/// <summary> 取消的任务</summary>
public List<T> CancelTask
{
get { return this.taskList.ToList().FindAll(l => l.TaskCore.IsCanceled); }
}
/// <summary> 异常的任务 </summary>
public List<T> FaultTask
{
get { return this.taskList.ToList().FindAll(l => l.TaskCore.IsFaulted); }
}
/// <summary> 是否全部运行完 </summary>
public bool IsComplete
{
get { return (CompleteTask.Count + CancelTask.Count + FaultTask.Count) == TotalCount; }
}
/// <summary> act:上一任务完成下一任务开始要处理的方法 </summary>
public TaskListManager(Action<Task<int>, T> act)
{
_act = act;
if (taskList == null)
taskList = new LinkedList<T>();
if (cts == null)
cts = new CancellationTokenSource();
}
public TaskListManager()
{
if (taskList == null)
taskList = new LinkedList<T>();
if (cts == null)
cts = new CancellationTokenSource();
}
/// <summary> act:上一任务完成下一任务开始要处理的方法 allOver所有任务都处理完的处理的方法 </summary>
public TaskListManager(Action<Task<int>, T> act, Func<Task<int>, int> allOver)
{
_act = act;
_allOver = allOver;
if (taskList == null)
taskList = new LinkedList<T>();
if (cts == null)
cts = new CancellationTokenSource();
}
/// <summary> 运行结束 p1 = 上一任务 p2 = 调用的接口 r = 任务的结果</summary>
int ContinueWith(Task<int> pTask, T worker)
{
// 设置取消参数
if (cts.IsCancellationRequested)
{
return TaskResultID.CacelParam;
}
// 正在执行任务
//runTask = taskList.First(l => l.TaskCore.Id == pTask.Id);
runTask = worker;
// 触发任务交接
if (_act != null)
_act(pTask, runTask);
int result = worker.RunWork(cts.Token);
return result;
}
int TaskStartTask(T worker)
{
return worker.RunWork(cts.Token);
}
#endregion - 内部成员 End -E
/// <summary> 在末尾创建任务 p1=当前任务对应的接口 p2 = 是否自动运行</summary>
public void ContinueLast(T worker, bool autoRun=false)
{
// 不存在新增
if (taskList.Count == 0)
{
// 创建进程
Task<int> firstTask = new Task<int>(l => TaskStartTask(worker), cts.Token);
worker.TaskCore = firstTask;
runTask = worker;
taskList.AddFirst(worker);
return;
}
// 获取最后节点
T lastTask = taskList.Last.Value;
// 设置报错取消
lastTask.TaskCore.ContinueWith<int>(
l =>
{
cts.Cancel();
return TaskResultID.FaultParam;
},
TaskContinuationOptions.OnlyOnFaulted
);
// 增加当前任务
Task<int> addTask = lastTask.TaskCore.ContinueWith<int>
(
l => ContinueWith(l, worker),
cts.Token,
TaskContinuationOptions.None,
TaskScheduler.Default
);
worker.TaskCore = addTask;
worker.ParentTaskCore = lastTask.TaskCore;
taskList.AddLast(worker);
if (autoRun && this.IsCancel)
{
this.Start();
}
}
/// <summary> 执行任务 </summary>
public void Start()
{
// 触发完成事件
if (_allOver != null)
taskList.Last.Value.TaskCore.ContinueWith<int>(_allOver, cts.Token);
cts = new CancellationTokenSource();
if (taskList.First.Value.TaskCore.Status == TaskStatus.Created)
{
taskList.First.Value.TaskCore.Start();
}
//var find = FindNextWaitRun(taskList.First.Value);
//if (find != null)
//{
// find.TaskCore.Start();
//}
}
/// <summary> 查找最新可执行任务 </summary>
T FindNextWaitRun(T task)
{
var pTask = taskList.Find(task);
if (pTask != null)
{
if (pTask.Value.TaskCore.Status == TaskStatus.WaitingForActivation || pTask.Value.TaskCore.Status == TaskStatus.Created)
{
return pTask.Value;
}
else
{
if (pTask.Next != null)
{
return FindNextWaitRun(pTask.Next.Value);
}
else
{
return default(T);
}
}
}
else
{
return default(T);
}
}
/// <summary> 等待所有任务结束 p1 = 单位秒 超时限制</summary>
public void Wait(int millisecondsTimeout = 0)
{
if (millisecondsTimeout == 0)
{
Task.WaitAll(taskList.Select(l => l.TaskCore).ToArray());
}
else
{
Task.WaitAll(taskList.Select(l => l.TaskCore).ToArray(), millisecondsTimeout);
}
}
/// <summary> 停止所有任务 </summary>
public T Stop()
{
// 调用取消
cts.Cancel();
return this.runTask;
}
/// <summary> 暂停 </summary>
public T Pause()
{
TaskControlModel.Instance.IsPause = true;
return this.runTask;
}
/// <summary> 继续 </summary>
public void Continue()
{
cts = new CancellationTokenSource();
TaskControlModel.Instance.IsPause = false;
}
/// <summary> 清理任务 </summary>
public void ClearTask()
{
taskList.Clear();
cts = new CancellationTokenSource();
}
}
/// <summary> 控制参数 </summary>
public class TaskControlModel : BaseFactory<TaskControlModel>
{
bool isPause = false;
public bool IsPause
{
get { return isPause; }
set { isPause = value; }
}
}
}
3、定义任务执行状态
/// <summary> 任务的执行结果 </summary>
public class TaskResultID
{
/// <summary> 运行结束 </summary>
public static int CompleteParam { get { return -9999999; } }
/// <summary> 运行取消 </summary>
public static int CacelParam { get { return -8888888; } }
/// <summary> 运行报错 </summary>
public static int FaultParam { get { return -7777777; } }
}
四、示例
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace HebianGu.ComLibModule.TaskEx
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
for (int i = 0; i < 5; i++)
{
// 创建记事本任务
CaseTaskCore caseTaskCore = new CaseTaskCore();
caseTaskCore.FilePath = "notepad";
caseTaskCore.FileName = "notepad";
// 将记事本添加到任务管理器中
TaskListManager<CaseTaskCore>.Instance.ContinueLast(caseTaskCore, true);
}
}
}
public class CaseTaskCore : BaseTaskCore
{
string fileName;
/// <summary> 文件名称 </summary>
public string FileName
{
get { return fileName; }
set { fileName = value; }
}
string filePath;
/// <summary> 文件全路径 包含文件名 </summary>
public string FilePath
{
get { return filePath; }
set { filePath = value; }
}
Process p;
public override int RunCaseTaskWork(System.Threading.CancellationToken pToken)
{
Console.WriteLine("开始执行任务:" + this.GetType().Name);
// 启动进程
p = Process.Start(this.filePath);
return 0;
}
/// <summary> 停止任务 </summary>
public void Stop()
{
this.IsRestart = false;
if (p.HasExited)
return;
this.p.CloseMainWindow();
p.Kill();
}
}
}