线程Coroutines 和 Yield(转)

之前一直很纠结这个问题,在网上找到了这篇文章,给大家分享下: 
第一种方法:   
 void Start() 
    { 
        print("Starting " + Time.time);----------------------------------------1 
        StartCoroutine(WaitAndPrint(2));-------------------------------------2 
        print("Done " + Time.time);-------------------------------------------3 
    } 
    IEnumerator WaitAndPrint(float waitTime) 
    { 
        yield return new WaitForSeconds(waitTime);------------------------4 
        print("WaitAndPrint " + Time.time);----------------------------------5 
    }
 
该段代码的执行顺序是12435 
IEnumerator Start() 
    { 
        print("Starting " + Time.time);----------------------------------------1 
        yield return StartCoroutine(WaitAndPrint(2.0F));------------------------2 
        print("Done " + Time.time);------------------------------------------3 
    } 
    IEnumerator WaitAndPrint(float waitTime) 
    { 
        yield return new WaitForSeconds(waitTime);----------------------------4 
        print("WaitAndPrint " + Time.time);-----------------------------------------5 
    }
 
该段代码的执行顺序是12453 
   1. 在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。 
      2.在Unity3D中,StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启一个线程。 
          区别在于: 
               使用字符串作为参数,可以开启线程并在线程结束前终止线程, 
               相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法). 
         另外,使用字符串作为参数时,开启线程时最多只能传递 一个参数,并且性能消耗会更大一点; 
             而使用IEnumerator 作为参数则没有这个限制。
 
       3. 在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该 MonoBehaviour中的协同程序。 
      4. 还有一种方法可以终止协同程序,即将协同程序所在gameobject的active属性设置为false,当再次设置active为ture时,协同程 序并不会再开启;如是将协同程序所在脚本的enabled设置为false则不会生效。这 
是因为协同程序被开启后作为一个线程在运行,而 
MonoBehaviour也是一个线程,他们成为互不干扰的模块,除非代码中用调用,他们共同作用于同一个对象,只有当对象不可见才能同时终止这两个线 
  
程。然而,为了管理我们额外开启的线程,Unity3D将协同程序的调用放在了MonoBehaviour中,这样我们在编程时就可以方便的调用指定脚本 
  
中的协同程序,而不是无法去管理,特别是对于只根据方法名来判断线程的方式在多人开发中很容易出错,这样的设计保证了对象、脚本的条理化管理,并防止了重 
 名。 


注意:


  • 在unity C#中yield(中断)语句必须要在IEnumerator类型里

  • C#方法,方法的返回类型为IEnumerator,返回值如(eg: yield return new WaitForSeconds(2); 或者 yield return null;)。
  •  
    yield不可以在Update或者FixedUpdate里使用。
C#中的Coroutine与JavaScript中的区别:


    1:Coroutines 必须要是 IEnumerator 返回类型: 

IEnumerator MyCoroutine() 
        { 
//This is a coroutine } 

  2:在C#中要使用 yield return而不是yield : 
        Remember that we need to return an IEnumerable, so the Javascript yield; becomes yield return 0; in C#         IEnumerator MyCoroutine() 
            { 
                DoSomething(); 
             
yield return 0; 
            //Wait one frame, the 0 here is only because we need to return an IEnumerable 
             DoSomethingElse(); 
           } 
    since C# requires you to use the new operator to create objects, if you want to use WaitForSeconds  you have to use it like this: 


IEnumerator MyCoroutine() 
     { 
       DoSomething(); 
yield return new WaitForSeconds(2.0f); //Wait 2 seconds DoSomethingElse(); 
      }
 

3:调用Coroutine要使用 StartCoroutine 方法: 

public class MyScript : MonoBehaviour 
{ 
void Start() 
    { 
        StartCoroutine(MyCoroutine()); 
    } 
  
    IEnumerator MyCoroutine() 
    { 
//This is a coroutine } 
}

详细参考官网:http://docs.unity3d.com/Documentation/Manual/Coroutines.html

原文地址:https://www.cnblogs.com/eangulee/p/3566159.html