繁体   English   中英

理解协同程序的执行

[英]Understanding The Execution of Coroutines

我在Unity工作,但这只是一个C#问题所以我希望这是发布这个问题的正确部分。 无论如何,我仍然无法在脑中看到脚本的执行,特别是当有多个运行时它们都有不同的功能。

最近因为我将Update,FixedUpdate和Coroutine添加到我的“何时运行”列表中而变得更加复杂? 更新和修复更新我得到了要点。

至于Coroutine,我基本上理解它是一种功能,可以让我更准确地控制时间。 这是我知道我能做的唯一方法“收益返回新的WaitForSeconds(i);”

我的问题更多的是他们的执行顺序。 例如,如果我从更新调用协程(每帧运行一次)并且协程有一个waitforseconds(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会在每个“更新周期”上调用游戏对象上的Update和协同程序上的MoveNext 正在等待的协程只是被跳过 - 它不会阻止任何其他代码。

暂无
暂无

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

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