了解协程的执行

我在Unity工作,但这真的只是一个C#问题,所以我希望这是张贴这个的正确部分。 无论如何,我仍然无法想象我头脑中的脚本执行情况,特别是当有多个运行并且它们都具有不同的功能时。

最近变得更加复杂了,因为我已将Update,FixedUpdate和Coroutine添加到“When when this running”列表中了吗? 更新和固定更新我明白了。

至于Coroutine,我基本上明白这是一种功能,可以更精确地控制时序。 这是我知道我可以做的唯一方法:“返回新的WaitForSeconds(i);”

我的问题更多的是关于他们的执行顺序。 例如,如果我从更新(每帧运行一次)调用协同程序并且协程的等待时间为10(10),那么将暂停执行所有脚本? 有没有像一个中央时钟运行的一切? 更新不会再次运行,直到等待结束? 如果我有另一个包含不同协同程序的更新函数的脚本,并且两者都在同一时间运行,该怎么办?

也许我会模糊。 很难解释。 我已经在网上阅读了一些有关协程的信息,但没有一个真正以我可以想象的方式解释它。


你需要知道的第一件事是使用yield关键字并返回一个IEnumerable的函数变成迭代器。 它是编写实现IEnumerator的类的语法糖。

它们通常与foreach循环一起使用:

IEnumerable<string> GetFruits()
{
    yield return "Apple";
    yield return "Pear";
}

foreach (string fruit in GetFruits())
    Console.WriteLine(fruit);

这里发生的事情是GetFruits返回一个实现IEnumerator<string>的生成器对象。 它的MoveNext方法每次MoveNext运行原始GetFruits代码的一部分。 每次调用执行代码到下一个yield的语句,并使用的“返回值” yield设定Current发生器的性能。

foreach循环产生调用MoveNext并将Current存储到循环变量中的代码,这使得迭代更加可读,如下所示:

IEnumerator<string> fruitsGenerator = GetFruits().GetEnumerator();
while (fruitsGenerator.MoveNext())
{
    string fruit = fruitsGenerator.Current;
    Console.WriteLine(fruit);
}

但是你不限于在循环中使用迭代器。 您可以存储对生成器的引用并调用其MoveNext方法,例如每秒一次。 或者每当用户按下按钮。 或者您可以使用Current值来确定何时应该再次MoveNext

这正是Unity正在做的。 协程本质上是一个生成器对象(带有一些额外的信息,比如剩下多少时间,直到它再次被调用)。 当协程产生WaitForSeconds对象时,Unity会更新该协程的等待时间,并且不会再次调用该协程的MoveNext方法,直到等待时间结束。

除非协程仍处于“等待”状态,否则Unity的每个“更新周期”都会在您的协同程序上MoveNext游戏对象和MoveNext上的Update 。 正在等待的协程简单地被跳过 - 它不会阻塞任何其他代码。

链接地址: http://www.djcxy.com/p/53167.html

上一篇: Understanding The Execution of Coroutines

下一篇: How to clone Boost ASIO coroutine on fork?