在框架中,Web请求,资源的下载或加载会以任务的形式进行处理,Task作为框架的基础功能,所负责管理的就是这三类任务
打开工程,在Base文件夹下新建一个Task文件夹,并新建3个类文件
其中
ITask是任务接口,主要存储任务执行时所需的数据
ITaskAgent是任务代理接口,负责对任务进行处理(实际的处理逻辑则通过调用具体模块的代理辅助器执行,这一点在后面编写需要使用任务功能的模块时会涉及到)
TaskPool是任务池,使用链表与栈来维护任务与任务代理,并提供任务的添加与移除等操作
打开ITask,将其修改为接口,然后添加2个属性就可以了
/// <summary> /// 任务接口 /// </summary> public interface ITask{ /// <summary> /// 任务序列ID /// </summary> int SerialId { get; } /// <summary> /// 任务是否完成 /// </summary> bool Done { get; } }
在具体的模块中,会根据需求建立实现该接口的Task类
打开ITaskAgent类,将其也修改为接口,添加泛型与约束
/// <summary> /// 任务代理接口 /// </summary> /// <typeparam name="T">任务类型</typeparam> public interface ITaskAgent<T> where T : ITask { }
然后添加属性与方法
/// <summary> /// 获取任务。 /// </summary> T Task { get; } /// <summary> /// 初始化任务代理。 /// </summary> void Initialize(); /// <summary> /// 任务代理轮询。 /// </summary> void Update(float elapseSeconds, float realElapseSeconds); /// <summary> /// 关闭并清理任务代理。 /// </summary> void Shutdown(); /// <summary> /// 开始处理任务。 /// </summary> /// <param name="task">要处理的任务。</param> void Start(T task); /// <summary> /// 停止正在处理的任务并重置任务代理。 /// </summary> void Reset();
最后打开TaskPool类,为其添加泛型与约束
/// <summary> /// 任务池 /// </summary> /// <typeparam name="T">任务类型</typeparam> public class TaskPool<T> where T : ITask{ }
添加字段与属性,并在构造方法里进行初始化
/// <summary> /// 可用任务代理 /// </summary> private Stack<ITaskAgent<T>> m_FreeAgents; /// <summary> /// 工作中任务代理 /// </summary> private LinkedList<ITaskAgent<T>> m_WorkingAgents; /// <summary> /// 等待中任务 /// </summary> private LinkedList<T> m_WaitingTasks; /// <summary> /// 可用任务代理数量 /// </summary> public int FreeAgentCount { get { return m_FreeAgents.Count; } } /// <summary> /// 工作中任务代理数量 /// </summary> public int WorkingAgentCount { get { return m_WorkingAgents.Count; } } /// <summary> /// 任务代理总数量 /// </summary> public int TotalAgentCount { get { return FreeAgentCount + WorkingAgentCount; } } /// <summary> /// 等待中任务数量 /// </summary> public int WaitingTaskCount { get { return m_WaitingTasks.Count; } } public TaskPool() { m_FreeAgents = new Stack<ITaskAgent<T>>(); m_WorkingAgents = new LinkedList<ITaskAgent<T>>(); m_WaitingTasks = new LinkedList<T>(); }
然后添加任务代理的增加方法
/// <summary> /// 增加任务代理 /// </summary> /// <param name="agent">要增加的任务代理</param> public void AddAgent(ITaskAgent<T> agent) { if (agent == null) { Debug.LogError("要增加的任务代理为空"); } agent.Initialize(); m_FreeAgents.Push(agent); }
添加任务的增加与移除的方法
/// <summary> /// 增加任务 /// </summary> /// <param name="task">要增加的任务</param> public void AddTask(T task) { m_WaitingTasks.AddLast(task); } /// <summary> /// 移除任务 /// </summary> /// <param name="serialId">要移除任务的序列编号</param> /// <returns>被移除的任务</returns> public T RemoveTask(int serialId) { foreach (T waitingTask in m_WaitingTasks) { if (waitingTask.SerialId == serialId) { m_WaitingTasks.Remove(waitingTask); return waitingTask; } } //连同工作中的任务代理一起移除 foreach (ITaskAgent<T> workingAgent in m_WorkingAgents) { if (workingAgent.Task.SerialId == serialId) { workingAgent.Reset(); m_FreeAgents.Push(workingAgent); m_WorkingAgents.Remove(workingAgent); return workingAgent.Task; } } return default(T); } /// <summary> /// 移除所有任务 /// </summary> public void RemoveAllTasks() { m_WaitingTasks.Clear(); //重置所有工作中任务代理 foreach (ITaskAgent<T> workingAgent in m_WorkingAgents) { workingAgent.Reset(); m_FreeAgents.Push(workingAgent); } m_WorkingAgents.Clear(); }
最后添加任务池的轮询与关闭方法
/// <summary> /// 任务池轮询 /// </summary> public void Update(float elapseSeconds, float realElapseSeconds) { //获取第一个工作中任务代理 LinkedListNode<ITaskAgent<T>> current = m_WorkingAgents.First; while (current != null) { //如果当前工作中任务代理已完成任务 if (current.Value.Task.Done) { //就让它重置并从工作中任务代理中移除 LinkedListNode<ITaskAgent<T>> next = current.Next; current.Value.Reset(); m_FreeAgents.Push(current.Value); m_WorkingAgents.Remove(current); current = next; continue; } //未完成就轮询任务代理 current.Value.Update(elapseSeconds, realElapseSeconds); current = current.Next; } //有可用任务代理并且有等待中任务 while (FreeAgentCount > 0 && WaitingTaskCount > 0) { //出栈一个任务代理 ITaskAgent<T> agent = m_FreeAgents.Pop(); //添加到工作中任务代理 LinkedListNode<ITaskAgent<T>> agentNode = m_WorkingAgents.AddLast(agent); //获取一个等待中的任务 T task = m_WaitingTasks.First.Value; m_WaitingTasks.RemoveFirst(); //开始处理这个任务 agent.Start(task); if (task.Done) { agent.Reset(); m_FreeAgents.Push(agent); m_WorkingAgents.Remove(agentNode); } } } /// <summary> /// 关闭并清理任务池 /// </summary> public void Shutdown() { while (FreeAgentCount > 0) { m_FreeAgents.Pop().Shutdown(); } foreach (ITaskAgent<T> workingAgent in m_WorkingAgents) { workingAgent.Shutdown(); } m_WorkingAgents.Clear(); m_WaitingTasks.Clear(); }现在对Task功能的编写已经基本完成了,我们将在下一篇编写DownLoad模块时对Task功能进行具体应用