【Unity】理解協程的原理1——實現一個自己的WaitForSeconds

協程的所能達到的效果就是在指定的時間點上執行需要執行的代碼,Unity中開始一個協程的函數是StartCoroutine,而提供的延遲的類有以下幾種分別是

            new WaitForEndOfFrame;      //等待一幀
            new WaitForFixedUpdate;     //等待一個FixedUpdate(固定時間間隔)
            new WaitForSeconds;         //等待X秒
            new WWW;                    //等待外部資源加載完畢

本文就針對其中的WaitForSeconds實現進行探究。 因爲在開發過程中,很多時候會遇到一種情況就是,超時或者是符合某種條件就繼續運行,使用系統提供WaitForSeconds已經無法滿足要求了,這時候有兩種解決方法,一種是使用StopCoroutine來停止協程,但是對於Unity來說,這種行爲會造成很大的開銷,那麼可以採用重寫WaitForSeconds,使它能達到我們的要求。以下是我認爲的WaitForSeconds的實現:

    /// <summary>
    /// 任務擴展
    /// </summary>
    static class CTaskExtend
    {
        static public IEnumerator WaitForSeconds(float second)
        {
            DateTime init_dt = DateTime.Now;
            TimeSpan time;
            while(true)
            {
                time = DateTime.Now - init_dt;
                if(time.TotalSeconds <= second)
                {
                    yield return null;
                }
                else
                {
                    break;
                }
            }
        }
    }


調用的方法與Unity差不多:

yield return CTaskExtend.WaitForSeconds(delayTime);

看上去似乎非常簡單,確實也是非常簡單,那麼如果遇到之前說的那一種情況(超時或者是符合某種條件就繼續運行),這裏需要做怎麼樣的改動呢?如下:

    /// <summary>
    /// 任務擴展
    /// </summary>
    static class CTaskExtend
    {
        public delegate bool CondDelegate();
        static public IEnumerator WaitForSeconds(float second, CondDelegate cond = null)
        {
            DateTime init_dt = DateTime.Now;
            TimeSpan time;
            while(true)
            {
                time = DateTime.Now - init_dt;
                if (time.TotalSeconds <= second && !cond())
                {
                    yield return null;
                }
                else
                {
                    break;
                }
            }
        }
    }

加上了一個回調函數,每次都會檢查這個函數是否爲true,如果爲true則停止等待。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章