簡體   English   中英

在 Unity3d 中“await”如何不被阻塞?

[英]How does "await" not block in Unity3d?

這是我擁有的代碼

using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;

public class NewMonoBehaviour : MonoBehaviour
{
    // Start is called before the first frame update


    [SerializeField]
    GameObject player;
    void Start()
    {

    }

    // Update is called once per frame
    async void Update()
    {
        if (Input.GetKeyDown("space"))
        {
            Debug.Log("Start");
            await Task.Delay(3000);
            Debug.Log("End");
        }

        if (Input.GetKey(KeyCode.A))
        {
            player.transform.Translate(new Vector3(-1,0,0) * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.D))
        {
            player.transform.Translate(new Vector3(1,0,0) * Time.deltaTime);
        }
    }
}

當我按下空格鍵時,即使延遲還沒有結束,我也可以左右移動。 此外,我可以反復按空格來獲得

Start
Start
Start
End
End
End

這就像我想要的那樣工作,但我想了解為什么。 我想這個方法中的所有內容都會被阻塞,直到 Task.Delay 完成。

您使整個Update()方法async

async void Update()
{//whatever needs to be done in a frame}

渲染Update方法異步運行,以便 Unity 在繼續之前不會等待它返回。 它繼續在所有其他對象上調用Update() ,執行其操作,渲染幀,直到在同一對象上的下一幀上達到相同的async void Update() 所以,它可以對

if (Input.GetKey(KeyCode.A))
    {
        player.transform.Translate(new Vector3(-1,0,0) * Time.deltaTime);
    }

在后續幀中,即使前一幀Update()正在等待await Task.Delay(3000) 這就是為什么你得到你得到的結果。

順便說一句, async void Update()恕我直言是個壞主意,因為當各種Update()方法在意外的時間返回不同的值並在意外的時間修改變量時,您會得到意外的結果。 我會保持Update()同步,並最終讓它調用一個async方法來做你需要的。

套用MSDN:異步編程並使用基於任務的異步模式 (TAP)

基於 .NET Task 的異步模型由 Task 和 Task 類型以及 C# 中的 async 和 await 關鍵字公開

我意識到理解這些文件並不總是那么容易。 所以基本上發生的事情是,當您在方法中await ,返回值在調用await Update()被“保留”。 一旦等待完成,調用者將收到該值,這將級聯調用樹。

重要的是每個單獨的方法調用都變得異步。 我認為它就像你給員工的工作卡一樣。 你可以繼續給他們新的卡片,每次他們完成工作時,他們會把卡片還給你,你做你必須做的事情。 員工可能會選擇先做簡單的事情,所以你很可能會以不同的順序取回卡片,但這並不重要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM