C#多线程多任务管理实战:基于策略模式与事件回调的实现
本文详细阐述在C#中进行多线程与多任务管理的具体实现方法。通过构建包含枚举状态、策略执行器(IExecuter)及管理器(TaskManager)的架构,演示了如何同时启动多个异步任务、实时监控执行进度(Rate)与最终状态(Status),并处理任务的暂停、恢复与强制终止等生命周期操作。
核心设计思路
要实现可控的多任务管理,我们需要解决三个核心问题:任务的生命周期追踪、具体的业务执行逻辑解耦、以及线程安全的并发控制。
- 抽象执行层:采用策略模式,通过
IExecuter接口隔离具体业务代码,使Task类只关注调度而非实现细节。 - 状态同步:使用泛型委托(
TaskDelegate<T>)将任务内部的变化(如进度、状态变更)抛给外部观察者,实现UI或日志层的实时更新。 - 集中管控:由
TaskManager统一维护任务列表,提供添加、启动、停止、删除等原子操作。
环境准备
本项目基于标准 .NET Framework 环境,无需引入第三方库。主要依赖 System.Threading 命名空间进行原生线程管理。
具体操作步骤
第1步:定义任务状态枚举与数据载体
首先建立标准化的状态机,确保所有任务拥有统一的运行标识。同时创建泛型委托用于数据传递。
public enum TaskStatus
{
wait = 0,
working = 1,
stop = 2,
suspend = 3,
complete = 4,
fail = 5,
other = 99
}
// 通用参数基类结构示例
public delegate void TaskDelegate<T>(T para); // 需根据实际泛型约束调整
public class ParaStatus { public Guid TaskId { get; set; } public TaskStatus Status { get; set; } }
public class ParaProcess { public Guid TaskId { get; set; } public double Rate { get; set; } }
第2步:实现任务封装类 (Task)
Task 类封装了单个线程的生命周期。它持有对执行器(IExecuter)的引用,并提供 Start, Suspend, Resume, Stop 等方法来控制底层线程。
public class Task
{
public TaskDelegate<ParaStatus> taskStatus;
public TaskDelegate<ParaInfo> taskInfo;
public TaskDelegate<ParaProcess> taskProcess;
private TaskStatus _status = TaskStatus.wait;
private IExecuter _Executer { get; set; }
private Guid _taskId;
private Thread thread;
private string _name;
public Task(Guid id, IExecuter Executer)
{
_taskId = id;
_Executer = Executer;
_Executer.TaskId = id;
_Executer.Task = this;
}
// 启动线程并更新状态
public void Start()
{
if (thread == null || thread.ThreadState == ThreadState.Stopped)
{
thread = new Thread(_Executer.Do);
}
thread.Start();
ChangeStatus(TaskStatus.working);
}
// 安全地终止线程
public void Stop()
{
if (thread != null && thread.IsAlive)
{
try
{
thread.Abort(); // 注意:Abort在现代C#开发中应谨慎使用,建议配合CancellationToken
}
catch { }
}
ChangeStatus(TaskStatus.stop);
}
private void ChangeStatus(TaskStatus s)
{
_status = s;
ParaStatus ps = new ParaStatus(_taskId) { Status = _status };
if (taskStatus != null) taskStatus(ps);
}
public Guid TaskId { get { return _taskId; } }
public TaskStatus Status { get { return _status; set { _status = value; } } }
}
第3步:定义执行接口与示例
定义 IExecuter 接口,具体的业务逻辑(如下载文件、数据处理)在此实现。此处提供一个简单循环作为Demo。
public interface IExecuter
{
Guid TaskId { get; set; }
Task Task { get; set; }
void Do();
}
public class Executer : IExecuter
{
public Guid TaskId { get; set; }
public Task Task { get; set; }
public void Do()
{
for (int i = 1; i <= 100; i++)
{
if (Task.taskProcess != null)
{
Thread.Sleep(1000);
ParaProcess pp = new ParaProcess(TaskId) { Rate = (double)i / 100 };
Task.taskProcess(pp); // 通知外部进度
}
}
Task.ChangeStatus(TaskStatus.complete);
}
}
第4步:构建任务管理器 (TaskManager)
管理器负责增删改查任务集合。在删除任务时,需先调用 Stop() 确保线程退出,再通过轮询检查线程状态以避免资源死锁。
public class TaskManager
{
public List<Task> Tasks = new List<Task>();
public Task AddTask(Task task)
{
try
{
Tasks.Add(task);
task.Wait(); // 初始化为等待状态
}
catch (Exception e) { /* 记录异常 */ }
return task;
}
public void DeleteTask(Task task, bool deleteFile)
{
task.Stop();
// 等待线程真正终止
while (task.Status == TaskStatus.working)
{
Thread.Sleep(50);
}
if (Tasks.Contains(task))
{
Tasks.Remove(task);
}
}
}
完成判断
当以下条件满足时,视为系统搭建完毕:
- 能够通过 TaskManager 实例化并添加具有不同业务逻辑的 Task。
- 调用 Start() 后,taskProcess 回调能持续触发并输出进度数据。
- 调用 DeleteTask() 后,该任务从列表中移除且不再占用线程资源。
简要总结
上述代码提供了一种经典的C#多线程任务管理模式。虽然使用了较底层的 Thread API,但通过接口抽象和状态机机制,成功实现了任务的可控性。在实际生产环境中,建议将 Thread.Suspend/Abort 替换为更安全的 CancellationTokenSource 方案以应对更复杂的异步场景。
以上就是C#多线程多任务管理实战的详细内容,更多关于C#并发编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









