【Unity】 HTFramework框架(十八)Coroutiner协程管理与调度

更新日期:2019年9月27日。
Github源码:[点我获取源码]

Coroutiner协程调度器简介

协程作为Unity中使用频繁的异步处理方式,Coroutiner的作用就是对其进行统一的管理与监控。

比如,通过Coroutiner启动的协程,将会全程处于Coroutiner的监控中,在编辑器中可以通过启动CoroutinerTracker追踪面板查看协程的运行状态、运行耗时、运行次数、启动位置等,可手动重启、终止任意协程,即便该协程已经停止了生命周期,也可以重启唤醒,如果是带参数的协程,也会重现其启动时传入的实参。

使用Coroutiner协程调度器

启动一个协程

Coroutiner的使用非常简单,一句话就OK了,只不过目前只支持最多带两个参数的协程方法,后续会增加:

	//启动协程 Coroutine1
	Main.m_Coroutiner.Run(Coroutine1);

    IEnumerator Coroutine1()
    {
        yield return YieldInstructioner.GetWaitForEndOfFrame();
        Debug.Log("协程 Coroutine1 执行!");
    }

重启、终止一个协程

在Coroutiner中,一个协程方法(比如上文的Coroutine1)可以被启动N多次(Run),每次启动后都会产生完全独立的执行分支,各自进行自己的生命周期互不干涉,如要想要截获到协程方法(比如上文的Coroutine1)的某一次执行分支,则只能通过ID来获取:

		//Run 启动一个新的协程分支,会返回该分支ID
        string id1 = Main.m_Coroutiner.Run(Coroutine1);
        string id2 = Main.m_Coroutiner.Run(Coroutine1);

通过ID获取到协程的执行分支后,我们可以获取这个分支的执行状态,强行终止这个分支,或者针对已经停止的执行分支进行重启:

        string id1 = Main.m_Coroutiner.Run(Coroutine1);
        string id2 = Main.m_Coroutiner.Run(Coroutine1);

        //id1 的执行分支是否仍然处于运行中
        Debug.Log(Main.m_Coroutiner.IsRunning(id1));

        //终止 id1 分支
        Main.m_Coroutiner.Stop(id1);

        //重启 id1 分支
        Main.m_Coroutiner.Rerun(id1);

注意:调用Rerun重启分支之后,如果该分支处于运行中,则会被中途终止,并重新执行!这可用于某些全局只允许执行一个分支的协程方法!

协程实时监视面板

在运行时,点击框架实体Coroutiner子物体上的Coroutiner Tracker按钮,可打开协程监视面板:
在这里插入图片描述
我们键入如下测试代码:

/// <summary>
/// 请输入类注释
/// </summary>
public class Test : MonoBehaviour
{
    private CoroutineClass _coroutineClass = new CoroutineClass();

    private void Start()
	{
        Main.m_Coroutiner.Run(Coroutine1);
        Main.m_Coroutiner.Run(Coroutine2);
        Main.m_Coroutiner.Run(Coroutine3);
        //Coroutine4 启动两个分支
        Main.m_Coroutiner.Run(Coroutine4, "鸿蒙");
        Main.m_Coroutiner.Run(Coroutine4, "麒麟");
        Main.m_Coroutiner.Run(_coroutineClass.CoroutineClass1);
    }

    IEnumerator Coroutine1()
    {
        yield return YieldInstructioner.GetWaitForEndOfFrame();
        Debug.Log("协程 Coroutine1 执行!");
    }

    IEnumerator Coroutine2()
    {
        yield return YieldInstructioner.GetWaitForEndOfFrame();
        Debug.Log("协程 Coroutine2 执行!");
    }

    IEnumerator Coroutine3()
    {
        while (true)
        {
            yield return YieldInstructioner.GetWaitForSeconds(1);
            Debug.Log("协程 Coroutine3 执行!");
        }
    }

    IEnumerator Coroutine4(string value)
    {
        yield return YieldInstructioner.GetWaitForEndOfFrame();
        Debug.Log("协程 Coroutine4 执行!参数:" + value);
    }
}

public class CoroutineClass
{
    public IEnumerator CoroutineClass1()
    {
        yield return YieldInstructioner.GetWaitForEndOfFrame();
        Debug.Log("协程 CoroutineClass1 执行!");
    }
}

将Test挂入场景,然后运行:
在这里插入图片描述
打开监视面板:
在这里插入图片描述
面板上显示的5条数据就是我们启动的5个种类的协程,会显示其所属的对象类型和名称,如果是MonoBehaviour对象则会显示其挂载目标,然后还有该协程方法的全名,后方[1]数字为其启动的分支数量,比如上文的Coroutine4协程,就启动了两次。

点击每一条数据,会打开分支详细列表:
在这里插入图片描述
列表中会展示每个分支的ID、执行状态(Running 执行中、Finish 生命周期结束、Stoped 外部原因终止)、启动时间(分:秒:毫秒)、停止时间(分:秒:毫秒)、耗时(停止时间 - 启动时间)、重启次数等。

选中某一个分支,在面板下方会显示其启动时的堆栈信息,用于追踪其启动位置。

在上文中我们可以看到只有Coroutine3协程仍然还在运行,因为该协程是以秒做单位无限循环。

协程Coroutine4拥有两个分支,我们可以分别手动重启其的两个分支,参数会自动传入其首次启动时的实参(鸿蒙、麒麟)。

通过监视面板,我们可以非常直观的查看哪些协程被高频率的启动了N个分支,哪些协程执行一次耗时极高,哪些协程明明该结束了却还在偷偷的执行着…从而重新设计我们的代码。

当然,很显然的是,一些已经结束了生命周期的协程依然还被Coroutiner所保留,如果想要彻底清理他们,调用如下接口就可以了:

        //清理所有未处于运行状态的协程及分支
        Main.m_Coroutiner.ClearNotRunning();

当然,代价是,被清理后,你将无法再通过Rerun进行重启,必须使用Run另行创建分支!

运行时检视面板

在编辑器中运行时将会出现运行时检视面板(Runtime Data),主要用以调试或数据监测,目前面板如下:
在这里插入图片描述
1.No Runtime Data!

猜你喜欢

转载自blog.csdn.net/qq992817263/article/details/91492838
今日推荐