如何在异步中执行 WaitUntil?

How to do WaitUntil in async?

我在网上看到的async中的await都是在教我如何“等待一段时间”,这不是我想要的。

我想让它等到满足某个条件。

刚刚好

yield return new WaitUntil(()=>conditionIsMet);

Coroutine.

我想做类似的事情

await Task.WaitUntil(()=>conditionIsMet);

这可能吗?

请问有人能帮帮我吗?

非常感谢您的帮助。

您可以创建自己的 ConsitionCheker 方法,并在您的 MainFunction 中使用它来获取等待条件结果的布尔值

 public async Task<bool> CheckCondition()
        {
            While(true){
               // check the condition
               if(mycondition is true)
                  break;
            }
            return true;
        }



 public void Do(bool consitionResult)
    {
        if(consitionResult){
        // codes
        }
    }

用法:

public  async void Test()
        {
            // waiting for condition met
            // pass the condition result
            Do(await CheckCondition());
        }

这基本上不会像

public static class TaskUtils
{
    public static Task WaitUntil(Func<bool> predicate)
    {
        while (!predicate()) { }
    }
}

虽然为了您的爱 CPU 我实际上宁愿给您的任务一定的睡眠间隔,例如

public static class TaskUtils
{
    public static async Task WaitUntil(Func<bool> predicate, int sleep = 50)
    {
        while (!predicate())
        {
            await Task.Delay(sleep);
        }
    }
}

现在你可以,例如使用像

这样的东西
public class Example : MonoBehaviour
{
    public bool condition;

    private void Start()
    {
        Task.Run(async ()=> await YourTask());
    }

    public async Task YourTask()
    {
        await TaskUtils.WaitUntil(IsConditionTrue);
        // or as lambda
        //await TaskUtils.WaitUntil(() => condition);

        Debug.Log("Hello!");
    }

    private bool IsConditionTrue()
    {
        return condition;
    }
}

您可以使用 UniTask 插件,它为 Unity 提供高效的免费分配 async/await 集成。

它有很多功能并且易于使用。
首先从 here 下载它,然后将它包含在您的项目中并像这样使用它:

using Cysharp.Threading.Tasks;
using UnityEngine;

public class Test : MonoBehaviour
{
    bool _condition;
    // Start is called before the first frame update
    void Start()
    {
        _ = ProcessAsyncTask();
    }

    public async UniTask ProcessAsyncTask()
    {
        await UniTask.WaitUntil( ()=> ConditionResult());
    }

    public bool ConditionResult()
    {
        // _condition 
        return _condition;
    }
}