协同程序与多线程的区别

协同程序(Coroutine)和多线程有一些相似之处,但并不是同一个东西。

协同程序的本质是把一个函数(routine)拆成几段来执行,通过 yield 关键字暂停当前片段并等待协同程序的返回。

多线程在多核处理器的环境下可以真正并行运行;而协同程序在任意时刻只有一个代码片段在执行。

正因为协同程序始终只有一个片段在运行,所以不需要像多线程那样考虑线程同步问题。多线程则必须处理各种同步和竞争条件。

协同函数的返回值必须是 IEnumerator,并使用 yield return 来返回结果。

注意:在 Unity 4.3.1 中,最大允许的协程数量为 10000000 个。

用法示例一:用作定时器

下面的示例演示如何用协同程序实现"启动 1 秒后再输出调试信息"的效果。

启动1秒后debug输出
                	void Start () {
                        StartCoroutine(func());  //立即返回
                        //StartCoroutine("func");//立即返回
                
                	}
                
                	// Update is called once per frame
                	void Update () {
                
                	}
                
                    IEnumerator func()
                    {
                
                        yield return new WaitForSeconds(1);//暂停当前函数片段,让出给其他片段执行,等待WaitForXXXXXX 返回
                
                        Debug.Log("1111111");
                
                
                    }

用法示例二:加载进度显示

下面的示例演示如何在每一帧更新一个 Text 控件的进度,从而实现加载进度的可视化显示。

   public Text txt;
                    // Use this for initialization
                    bool is_done;
                    int current;
                    int total;
                
                    void Start()
                    {
                        is_done = false;
                        current = 0;
                        total = 100;
                        txt = GameObject.Find("Text").GetComponent<Text>();
                
                        StartCoroutine(loding_sync());
                     //   StartCoroutine(    ()=>IEnumerator{} );
                
                    }
                
                    // Update is called once per frame
                    void Update()
                    {
                
                    }
                
                    IEnumerator loding_sync()
                    {
                
                        txt.text = "start to loaing";
                        yield return new WaitForSeconds(1.0f);
                
                        for (; current <= total; ++current)
                        {
                            yield return new WaitForEndOfFrame();
                            txt.text = current.ToString() + "%";
                            dosomethingelse();
                        }
                
                        txt.text = "Done";
                
                
                    }
                
                    void dosomethingelse()
                    {
                
                    }