嵌套协程生成的代码是什么

编辑原始问题进行详细说明:我正在使用统一协程来执行一些重型操作。 Unity是一个游戏引擎,代码在帧内运行。 如果操作密集,必须在协同程序中完成,否则完成框架需要很长时间。 这里的协程是DoTasks 。 如果你对unity引擎不熟悉,它们与迭代器很相似。

首先我必须说这些代码按照它们应该做的那样工作。 问题在于堆分配。 这就是说我会解释代码的作用。 当Init被调用时,它启动协程并进入DoTask ,然后进入foreach迭代currentTask.Execute() ,然后进入obj.CreateCellGosTask进行迭代。 现在是我们遇到的第一个收益回报,foreach链将结果返回到最初的协程(即StartCoroutine(DoTasks())),我们完成了框架。 在下一帧中,代码在执行的最后一行之后继续执行。 这是行为,工作正常。

public class TaskScheduler : MonoBehaviour
{
  private static volatile Task currentTask;
  public void Init(){
     StartCoroutine(DoTasks()); //Starts the coroutine
  }
  private IEnumerator DoTasks()
  {
     while(true){
       foreach (object b in currentTask.Execute())
       {
         yield return b;
         //Do something
       }
     }
  }



public class Task
{
private Cell cell;    
public IEnumerable Execute()
{
    foreach (object b in cell.CreateCellGosTask()){
      yield return b;
    // Do something
    }
}

收益率回报率不重要。 在所有嵌套迭代器中,它返回null。

问题是关于堆分配。 由于编译器生成实现IEnumerable的隐藏 (我认为),代码会创建垃圾。 不幸的是,垃圾收集是一件大事。

最终目标是在foreach链中将堆分配归零(StartCoroutine不重要)。因此,问题是编译器生成的代码以及它如何创建Enumerable和Enumerator类? 我的意思是DoTasksExecute的确切生成代码。 然后我可以输入完全相同的代码,并创建并返回一个结构而不是类。


(您可能更愿意跳过我的简短说明,下面用大写字母!)

我可能会误解你想要做的事情,但是,

1)协程与线程完全无关。

(Unity根本不使用线程,如果你需要创建一个线程(比如处理),你需要使用一个线程管理器(有很多可用的,或者你自己写的),但是它与协程无关。)

2)协程没有回报价值。 你只是yield return null来跳过一个框架或当你完成时打破。

一些笔记,

http://answers.unity3d.com/answers/966469/view.html http://answers.unity3d.com/answers/1119978/view.html

那是关于“你怎么称呼'不止一次协程'的结果的讨论”,这与你所问的有关。 (当我自己问这个时,就出现了... https://stackoverflow.com/a/34550206/294884 ...我当然没有意识到!)

我希望这有助于某种方式!

终于

4)你不能以任何有意义的方式嵌套协程。

你只是“开始另一个新的协同程序”。 你懂? 你所指的是要么“等到”完成另一个,要么“继续”,并且一次开始几个。

有关此问题的Google 100次讨论.. http://answers.unity3d.com/questions/14081/nested-coroutines.html或http://answers.unity3d.com/answers/515074/view.html

你不能以任何方式有意义地“嵌套协程”。

想象一下,你有一个带有秒表的坐在上面的厨房桌子。 你开始并运行一个秒表。 如果出于某种原因,你可以开始并运行其中的很多。 (他们中的一些“可能会自己启动其他人”,或者他们可能从其他地方开始。)

但是没有“嵌套”它们的概念,它们只是在那里跑步的秒表。

不要忘记,你所说的只是“它是运行每一帧的代码” - 无非就是如此。 (完全像Update() 。)

再一次-----我感觉到你实际上在Unity中线程化,这可以小心实现。 例子---

http://answers.unity3d.com/answers/443604/view.html

事实上,你完全不需要整个框架系统,也不需要协程,听起来就像你需要一个线程,也许有一个数学计算。


要绝对清楚.....

只是重复相同的观点,

public class TaskScheduler : MonoBehaviour

请注意,协程非常简单

根本没有连接到“任务”或“线程”

“协同程序”只不过是这样的:

一种运行每一帧的方式。

就是这样。 如您所知,游戏引擎环境为您提供了“每帧...”概念运行循环。

无论出于什么原因(比如移动一个物体,动画化一个怪物),我们要说的是,你想要做一些“每一帧”。 有两种方法可以在Unity中访问该功能。

(1)只需使用Unity为您提供的Update()准则函数:

Update()
   {
   if ( moveTheDinosaur )
     {
     // code here will run every frame,
     // frames are beautifully managed by Unity
     {

(2)只需使用协程:

launch coroutine showDinosaur
coroutine showDinosaur()
  {
  while(true)
     {
     // code here will run every frame,
     // frames are beautifully managed by Unity
     yield return null;
     // the formulaic line "yield return null"
     // indicates to the MonoBehaviour engine that's
     // the end of your processing this frame;
     // (Implementation details are unknown to us
     // and irrelevant)
     }
  }

请注意,事实上,只要您使用Unity一天以上,即使您是一位经验丰富的程序员,您也会意识到“Update()”一般说来完全愚蠢,您倾向于使用自己的协程来做一些事情每一帧。 (当然,“Update()”仅适用于快速演示或测试代码时的任何其他内容。)

再次重申一下,例证与“任务”或“线程”没有任何关系 - 我猜 - 当然,我可能是错的 - 就是你所得到的。 协程就是您如何访问Unity中的“框架系统”。 对于统一线程,请查看许多线程池辅助类型脚本或可用的系统之一,这些都很方便。

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

上一篇: what is the code generated by nested coroutines

下一篇: How to understand this Unity Coroutine?