0%

Coroutine

Coroutine

##定义

Process -> Thread -> Coroutine

协程(Coroutine)编译器级的,进程(Process)和线程(Thread)操作系统级的

优点

  • 非线程切换的执行效率,切换由程序本身控制

  • 不需要多线程的锁机制

参考文档

详见-本博客异步

补充

C#迭代器

迭代器

程序设计的软件设计模式,可在容器(container,例如链表阵列)上遍访的接口,设计人员无需关心容器的内容。百度百科

  • 迭代器是产生值的有序序列的一个语句块。是实现函数成员的方式。
  • 迭代器块在C#语法中不是独特的元素,它们在几个方面受到限制,并且主要作用在函数成员声明的语义上,它们在语法上只是语句块而已。
IEnumeraber IEnumerator

C# IEnumerator的详解

其他详见 Unity脚本编程-第八章

corountine_1

####糖块yield

yield 关键字向编译器指示它所在的方法是迭代器块

作用

将当前集合中的元素立即返回

  • yield return 返回元素
  • yield break 终止迭代
注意
  • 返回类型必须为 IEnumerable、IEnumerable、IEnumerator 或 IEnumerator
  • 参数前不能使用ref和out关键字
  • 匿名方法中 不能使用yield
  • unsef中不能使用
  • yield return 不能置于 try-catch 块中。 可置于 try-finally 语句的 try 块中。 yield break 能 try 块或 catch 块, 不置于 finally 块

Lua

编程语言Lua从5.0版开始支持协程的概念,极大的扩展了Lua的能力。Lua的协程通过扩展库coroutine来实现,其中的所有函数如下(具体可以参考Lua的官方manual)

1
`coroutine.create``coroutine.resume``coroutine.running``coroutine.status``coroutine.wrap``coroutine.yield`

当前运行的代码可以看作运行在主协程中(就像C程序的main运行在主线程中),通过create可以创建一个协程,resume以运行此协程,直到新协程调用yield程序才能返回到”主协程“中运行。

coroutine.create()

函数参数:接收单个参数,该参数是coroutine的主函数,即resume会执行的函数

函数返回值:返回其控制器,一个对象为thread的对象

函数作用:creat函数创建一个新的coroutine,定义了协程内的任务流程。从面对对象的角度来看,可以看成是coroutine类创建了一个对象co

coroutine.resume(co,[val1,val2,…])

函数参数:第一个参数即creat的返回值,一个thread对象。第二个参数是coroutine中执行需要的参数,是一个变长参数,可以传入任意多个。

函数返回值:当程序运行没有错误的时候,返回true,同时返回前一个调用coroutine.yield中传入的参数。如果有错误,返回错误false以及错误信息。

函数作用:当第一次调用coroutine的resume方法的时候,其从主函数第一行开始执行,之后再coroutine开始运行后,它会一直运行到自身终止或者是coroutine的下一个yield函数。

coroutine.yield(…)

函数参数:传入变长参数

函数返回值:返回在前一个resume中传入的参数值

函数作用:挂起当前的执行协程。该协程不能是一个C函数,一个元表或一个迭代器

coroutine.running():返回当前正在执行的协程

coroutine.status():返回当前协程的状态,有running/suspended/normal/dead等。

Unity协程实现

原理

Unity脚本编程

生命周期

​ 通过设置MonoBehaviour脚本的enabled对协程是没有影响的,但如果 gameObject.SetActive(false) 则已经启动的协程则完全停止了,即使在Inspector把gameObject 激活还是没有继续执行。也就说协程虽然是在MonoBehvaviour启动的(StartCoroutine)但是协程函数的地位完全是跟MonoBehaviour是一个层次的,不受MonoBehaviour的状态影响,但跟MonoBehaviour脚本一样受gameObject 控制,也应该是和MonoBehaviour脚本一样每帧“轮询” yield 的条件是否满足。

####开启函数

1
2
3
StartCoroutine(Test_00()); // IEnumerator
StartCoroutine("Test_01");
StartCoroutine(Test_02(5, 9));

终止函数

  • StopCoroutine(“name“)
  • StopAllCoroutines
  1. 它们只能终止改MonoBehaviour中的协程

  2. 还有一种方法可以终止协同程序,即将协同程序所在gameobject的active属性设置为false,当再次设置active为ture时,协同程序并不会再开启;如是将协同程序所在脚本的enabled设置为false则不会生效。-原因见上面

雨松momo

####yield

yield return 0 or yield return null:程序在下一帧中从当前位置继续执行

yield return 1,2,3,……: 程序等待1,2,3…帧之后从当前位置继续执行

yield return new WaitForSeconds(n):程序等待n秒后从当前位置继续执行

yield new WaitForEndOfFrame():在所有的渲染以及GUI程序执行完成后从当前位置继续执行

yield new WaitForFixedUpdate():所有脚本中的FixedUpdate()函数都被执行后从当前位置继续执行

yield return WWW:等待一个网络请求完成后从当前位置继续执行

yield return StartCoroutine():等待一个协程执行完成后从当前位置继续执行

true

False

备注:曾经尝试在协程中加入停止后从新启用的功能,怕是个智障。

Bool isTodo;

ie test(){

​ while(isTodo){

​ }

yiled return

Do Fun();

}