首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由嵌套协同线生成的代码是什么?

由嵌套协同线生成的代码是什么?
EN

Stack Overflow用户
提问于 2016-01-14 07:13:45
回答 1查看 1.2K关注 0票数 2

编辑了最初的问题来详细说明:,我正在使用统一协同来执行一些繁重的操作。统一是一个游戏引擎,代码在帧内运行。如果一个操作是密集的,它必须在协同工作,否则它需要很长的时间来完成一个框架。这里的协同线方法是DoTasks。如果您不熟悉统一引擎,则它们类似于迭代器。

首先,我必须说,这些代码的作用就像它们应该做的那样。问题在于堆分配。那就是说我会解释密码是怎么做的。当调用Init时,它启动协同线并进入DoTask,然后在foreach中迭代currentTask.Execute(),然后进入obj.CreateCellGosTask进行迭代。现在,我们遇到的第一个屈服返回,链和返回结果的初始协同线(即StartCoroutine(DoTasks(),我们完成了框架。在下一个框架中,代码在执行的最后一行之后继续在链中继续。这就是行为,而且运作良好。

代码语言:javascript
复制
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不重要)中实现堆分配为零,问题是编译器生成了哪些代码,以及它如何创建可枚举类和枚举器类?我指的是DoTasksExecute生成的精确代码。然后,我只需键入完全相同的代码,创建并返回一个结构,而不是一个类。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-14 12:51:49

(你可能更喜欢跳过我下面大写字母的简短解释!)

我可能误解了你想做的事,但是,

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

(统一根本不使用线程。如果您需要创建一个线程(比如处理),您需要使用线程管理器(有很多可用的线程,或者编写自己的线程管理器).但这与合作关系无关。)

2)协同线没有返回值。你只需要跳过一个框架或者在你完成后中断。

一些笔记,

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

这是一次关于“你如何称呼”‘合作不止一次’的结果的讨论,这与你要问的内容有某种关系。(当我自己问这个. https://stackoverflow.com/a/34550206/294884 .我当然没有意识到!)

我希望这在某种程度上有帮助!

只是最后

4)你不能用任何有意义的方式来嵌套协同。

你只是在“开始另一个新的合作机制”。你知道?你所指的要么只是“等到”一个人运行完另一个,要么是“向前走”,然后一次启动几个。

谷歌对此进行了100多年的讨论http://answers.unity3d.com/questions/14081/nested-coroutines.htmlhttp://answers.unity3d.com/answers/515074/view.html

你不可能以任何方式有意义地“筑巢合作”。

想象一下,你有一张摆着秒表的厨房桌子。你启动并运行秒表。如果出于某种原因,您可以启动和运行其中的许多。(他们中的一些人“可能是自己开始的”,也可能是从哪里开始的。)

但是没有“筑巢”的概念,他们只是在那里跑的秒表。

别忘了,你说的只是“运行每个帧的代码”--仅此而已。(和Update()完全一样。)

我又一次--我有种感觉,你真正想要的是在团结中的线程,这是可以小心实现的。例子

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

实际上,你不想和整个框架系统有任何关系,也不想和协作系统有任何关系,听起来你需要一条线--也许是一种数学计算。

绝对清楚.

为了重复同样的观点,

代码语言:javascript
复制
public class TaskScheduler : MonoBehaviour

注意,协同机制非常简单

根本没有与“任务”或“线程”的连接。

“协同线”只不过是这样:

一种运行每一个帧的方法。

仅此而已。如你所知,游戏引擎环境给你一个“每一帧.”概念运行循环

不管出于什么原因(比如说. )移动一个物体,动画一个怪物)你想做一些“每一个帧”。在统一中,有两种方法可以获得这种能力。

(1)只需使用联合为您提供的Update()拟函数:

代码语言:javascript
复制
Update()
   {
   if ( moveTheDinosaur )
     {
     // code here will run every frame,
     // frames are beautifully managed by Unity
     {

(2)只需使用协同线:

代码语言:javascript
复制
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)
     }
  }

请注意--实际上--如果您是一名经验丰富的程序员,只要使用了一天以上,您就会意识到"Update()“这件事通常是完全愚蠢的,您倾向于使用自己的协同机制来完成每一帧的工作。(当然,"Update()“仅用于测试代码时的快速演示或其他任何操作都很方便。)

再次重申,课程与“任务”或“线程”没有任何关系--我想,,我想,我当然错了, --这就是你想要的。Coroutines是您如何访问统一中的“框架系统”的方法。对于统一的线程处理,请查看许多可用的线程池-助手类型脚本或系统之一,这些脚本或系统非常方便。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34783651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档