繁体   English   中英

VS 中是否有来自 Unity3D 的 WaitUntil() 等价物?

[英]Is there an equivalent of WaitUntil() from Unity3D in VS?

在 Unity3D 中,您可以在协程中调用WaitUntil()直到语句变为真,例如当字符串不为空时。

string str="";
yield return new WaitUntil(()=>str!="");

我发现它非常有用,并希望在 VS 中使用它。

我设法通过创建 2 个类来做到这一点,比如 A 和 B,

class A
{
    public B b;

    public void Set(B bb)
    {
        b = bb;
        b.Str = "Test";
        b.ARE.Set();
    }
}

class B
{
    public string Str="";
    public AutoResetEvent ARE = new AutoResetEvent(false);

    public B()
    {
        Thread t = new Thread(Run);
        t.Start();
    }

    private void Run()
    {
        ARE.WaitOne();
        MessageBox.Show(String.Format($"The new string is {Str}");
    }
}

public static void Main()
{
    A a = new A();
    B b = new B();

    a.Set(b);
}

如您所见,B 的执行依赖于 A 设置 B 的AutoResetEvent

有没有办法让B自己处理?

我对Task.WhenAll和其他主题做了一些研究,但我真的不知道如何使用它,最后,我认为AutoResetEvent更适合这项工作。 但当然,我可能是错的!

附注。 我试图避免像while(Str=="");这样的事情while(Str==""); 因为它处理繁重!

即使它运行在不同的线程上,它仍然会占用不必要的内存和处理能力。

所以如果可能的话,我想完全推迟它,直到满足继续的条件。

非常感谢您的帮助!

非常感激!

我不是 Unity 专家,但据我所知,Unity 在游戏的每一帧都会调用Update()函数。 同样基于文档,它看起来像这样(Unity):

yield return WaitUntil(() => condition);

与此相同(纯C#):

while (!condition)
    yield return null;

没有详细说明强大的yield关键字,它们都返回一个IEnumerator 每次您“移动 [到] 下一个”迭代器的值时,都会执行该函数并返回下一个值。 只要有要返回的值,包括nullMoveNext()就会返回true

基本上, WaitUntil()似乎是某种 Unity 方言,用于在纯 C# 中等效。 我怀疑StartCoroutine()类的东西是一种类似的启动线程的机制(不确定这个)。

这是一个试图解释发生了什么的工作程序:

using System;
using System.Collections;
using System.Threading;

namespace ConsoleTest
{
    public class Program
    {
        private static int frameCounter;

        public class B
        {
            public string MyString { get; set; }

            public IEnumerator Run()
            {
                while (string.IsNullOrEmpty(MyString))
                {
                    Console.WriteLine("Nothing here yet..."); // This is printed every time MoveNext() is called on the iterator.
                    yield return null;
                }

                // MyString is not null anymore: print this.
                // This is also the end of the enumerator: no more values will be returned.
                Console.WriteLine("MyString has been set after we " + MyString);
            }
        }

        public static void Main()
        {
            // This simulates Unity's engine by generating one frame every 500ms.
            var frameTimer = new Timer(_ => UpdateFrameCounter(), null, 0, 500);

            // Creates an instance of B and get the enumerator by calling Run():
            var b = new B();
            var enumerator = b.Run();

            // As long as there are values being returned (by yield), stay in this loop.
            // Here, this means basically "as long as b.MyString is null or empty".
            while (enumerator.MoveNext())
            {
                // Demo purposes: block main thread for 1sec.
                Thread.Sleep(1000);

                // At frame 10, set the value of b.MyString
                if (frameCounter == 10)
                {
                    b.MyString = "reached 10 frames.";
                }
            }

            // We'll reach this when there are no more values to be returned, i.e. enumerator.MoveNext() == false.
            // Stop the timer and quit.
            frameTimer.Change(Timeout.Infinite, Timeout.Infinite);
            Console.WriteLine("Press any key to quit...");
            Console.ReadKey();
        }

        public static void UpdateFrameCounter()
        {
            // Update frame counter (-> Unity engine).
            Console.WriteLine($"Frame counter: {++frameCounter}");
        }
    }
}

编辑
要准确使用您的示例,您可以将b.Str设置为属性,然后在那里重置事件:

// In class B:
private string str = string.Empty; // private field

public string Str // public property
{ 
    get => str;
    set 
    { 
        str = value;
        ARE.Set(); // this is called each time b.Str value is set
    }
}

这样,当 A 或任何其他类设置 b.Str 的值时, ARE将自动设置,而 A 不必担心或知道它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM