【Unity】协程的同步使用
1 前言
协程一般是用于异步使用的,但有时候我们虽然使用了协程却希望其是同步执行的,所以这里就针对协程的同步使用来讨论一下。
2 同步使用
可通过协程结束的回调函数来实现同步。如为每一个协程提供完成回调函数,以及创建一个bool变量(或只提供一个,协程一替一个用),bool = false,在协程开启后,变量用于协程开始语句的下方while循环中:while(!bool){yield return null},这些协程开启后就会在下方while中持续等待,之后再在协程的完成回调函数中修改bool值为ture,进而等待结束继续推进。单看一层协程其是同步的,实际若是嵌套协程,每层都使用这种方法,也可以保证整个嵌套协程是同步执行的。
但这里实际是存在一个问题的,即第一个开启协程的函数通常不是协程函数,这样来看的话,最外层是没法进行等待的,因为协程并非真正的并行,若强行使用非协程式的死循环等待,那么整个程序就会卡死。这样来看,似乎只能实现所开启协程其内部逻辑的同步,开启协程后主逻辑还会继续往下走,无法保证主逻辑的同步。
好在Unity的生命周期函数Start也是可以写成协程形式的,只需将void Start()改为IEnumerator Start()即可。这样最上层的协程函数就有了,我们可以在Start中开启协程,同时让Start本身同步执行,进而保证了主逻辑的同步执行。虽然多多少少有些局限性,但至少是一种解决方案。
对用控制方法,那么除了上述的完成回调中调整变量值的方法外,还可以在每一层协程的完成回调函数中调用下一个协程,进而实现协程排序执行,只需在最内部的协程完成回调中控制一个变量值来让最外层主逻辑结束等待即可。但实际这种方式只能让嵌套协程按照顺序执行,一个完成才能执行下一个,而前一个方法可以让子协程在自身的任何位置执行并保证同步,所以此方法虽然简单但有局限性,根据需求选择即可。
例子:
//方法一(嵌套就不演示了)
IEnumerator Start()
{bool isFinish = false;this.StartCoroutine(A.FF_Init(() => //完成回调{isFinish = true;}));while (!isFinish) //等待{yield return null;}isFinish = false;this.StartCoroutine(B.FF_Init(() =>{isFinish = true;}));while (!isFinish){yield return null;}
}//方法二
IEnumerator Start()
{bool isFinish = false;this.StartCoroutine(A.FF_Init(() =>//完成回调{this.StartCoroutine(B.FF_Init(() =>{isFinish = true;}));}));//等待while (!isFinish) {yield return null;}
}
3 后记
暂时这么多吧。