猿问

Unity3d中的“await”如何不阻塞?

这是我的代码


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 完成。


隔江千里
浏览 213回答 2
2回答

德玛西亚99

你已经完成了async整个Update()方法。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可以满足您需要的方法。

精慕HU

异步编程并使用基于任务的异步模式 (TAP)基于 .NET 任务的异步模型由 Task 和 Task 类型以及 C# 中的 async 和await 关键字公开我意识到理解这些文档并不总是那么容易;所以基本上发生的情况是,当您await在方法中时,返回值在调用中“保留” await Update()。一旦等待完成,调用者将收到该值,这将在调用树中向上级联。重要的是每个单独的方法调用都变得异步。我认为它就像你给员工的工作卡。你可以不断地给他们新卡,每次他们完成工作时,他们都会把卡还给你,你就做你必须做的事。员工可能会选择先做简单的事情,这样您很可能会以不同的顺序取回卡片,但这并不重要。
随时随地看视频慕课网APP
我要回答