什么是嵌套协同程序生成的代码 [英] what is the code generated by nested coroutines

查看:116
本文介绍了什么是嵌套协同程序生成的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑原题阐述:我使用的统一协同程序来执行一些重型的操作。团结就是一个游戏引擎和代码框架内运行。如果操作是密集的,它具有在协程做否则它需要很长的时间为一帧来完成。在这里,协程的方法是 DoTasks 。如果你不熟悉的Unity引擎,它们类似于迭代器。

Edited the original question to elaborate: I'm using unity coroutines to perform some heavy duty operations. Unity is a game engine and codes are run within frames. If an operation is intensive, it has to be done in coroutines otherwise it takes a long time for a frame to complete. Here the coroutine method is DoTasks. If you are not familiar with the unity engine, they are similar to iterators.

首先我必须说这些代码工作,因为他们应该做的。问题是与堆分配。这就是说,我将解释什么代码做的。当初始化被称为它启动协程,并进入 DoTask ,然后进入里面的的foreach 来迭代 currentTask.Execute(),然后进入 obj.CreateCellGosTask 进行迭代。现在第一个回报收益率我们遇到,foreachs链的结果返回到初始协程(即StartCoroutine(DoTasks())),我们正在为框架完成。在下一帧中的代码继续在已执行的最后一行之后的链条。这是行为和正常工作

First of all I have to say these codes work as they are supposed to do. The problem is with heap allocation. That said I will explain what the codes do. When Init is called it starts the coroutine and goes into DoTask and then goes inside foreach to iterate currentTask.Execute() and then goes into obj.CreateCellGosTask to iterate. now the first yield return we encounter, the chain of foreachs return the result to the initial coroutine(namely StartCoroutine(DoTasks()) ) and we're done for the frame. On next frame the code continues in the chain right after the last line that was executed. This is the behaviour and works fine.

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。

What the yield returns is of zero importance. In all nested iterators it yield returns null.

问题是关于堆分配。该代码创建的垃圾由于这样的事实,编译器生成隐藏的实施IEnumerable的(我认为)。不幸的是垃圾收集是一个大问题团结。

The problem is about heap allocation. The code creates garbage due to the fact that the compiler generates hidden classes implementing IEnumerable (I think). Unfortunately Garbage collection is a big deal in unity.

的最终目标是在连锁的foreach零堆分配(StartCoroutine并不重要)。所以这个问题是完全编译器产生的代码是什么以及如何创建可枚举和枚举类?我的意思是 DoTasks 的具体生成的代码和执行。然后,我可以只输入完全相同的代码创建并返回一个结构,而不是一类。

The ultimate goal is to zero heap allocation in foreach chain (StartCoroutine is not important).So the question is exactly what code the compiler generates and How it creates Enumerable and Enumerator classes? I mean the exact generated code of DoTasks and Execute. Then I could just type the exact same code and create and return a struct instead of a class.

推荐答案

(您可能希望跳到下面大字我简短的说明!)

(You may prefer to skip to my short explanation in large letters below!)

我可能误解你想要做什么,但是,

I may misunderstand what you're trying to do, but,

1)协同程序已经完全无关的线程。

1) Coroutines have absolutely nothing to do with threads.

(统一根本不使用线程。如果你需要让一个线程(比如处理),你需要使用一个线程管理器(有许多可用的,或者自己写)。 ..但它是无关的协同程序。)

(Unity does not use threads at all. If you need to make a thread (say for processing) you need to use a thread manager (there are many available, or write your own) ... but it is unrelated to coroutines.)

2)协同程序没有返回值。你只要产量返回NULL 跳过框架或当你完成破..

2) Coroutines have no return value. You just yield return null to skip a frame or break when you're done..

的一些注意事项,

HTTP://answers.unity3d .COM /答案/ 966469 / view.html HTTP://answers.unity3d .COM /答案/ 1119978 / view.html

这是一个有关的你怎么骂协同程序的结果,不止讨论一旦的这是一种关系到你在问什么。 (那时,上来我自己也问这个的时候...... http://stackoverflow.com/a/34550206/294884 ...我当然不知道!)

that was a discussion about "how do you call 'the result of' coroutines more than once" which is kind of related to what you're asking. (That came up when I myself was asking this ... http://stackoverflow.com/a/34550206/294884 ... which I certainly did not realise!)

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

I hope this helps in some way!

刚最后

4)你不能以任何有意义的方式巢协同程序。

4) You can't nest coroutines in any meaningful way.

您只差出发另一种新的协同程序。你懂?什么你指的是不是只是等到一结束运行另一个,或走在前面和启动几个了一次。

You're just "starting yet another new coroutine". You know? What you're referring to is either just "waiting until" one finishes to run another one, or, "going ahead" and starting a few up at a time.

在此讨论的谷歌100S .. http://answers.unity3d.com/questions /14081/nested-coroutines.html HTTP://answers.unity3d。 COM /答案/ 515074 / view.html

Google 100s of discussions on this .. http://answers.unity3d.com/questions/14081/nested-coroutines.html or http://answers.unity3d.com/answers/515074/view.html

您不能有意义鸟巢协同程序以任何方式。

You can't meaningfully "nest coroutines" in any way.

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

Imagine you have a kitchen table with stopwatches sitting on it. You start and run a stopwatch. If for some reason you want to, you can start and run many of them. (Some of them "may start the others" themselves, or they may be started from elesewhere.)

但有没有嵌套他们中的概念,他们只是。秒表运行有

But there's no concept of "nesting" them, they're just stopwatches running there.

不要忘了,你是说是它是将运行每一帧码 - 没有什么比这更。 (酷似更新()

Don't forget, all you're saying is "it is code that will run each frame" - nothing more than that. (Exactly like Update().)

再一次-----我的感觉是你'重新实际上后穿线在Unity,可以谨慎来实现。举例---

Once again ----- I get the feeling that what you're actually after is threading in Unity, which can be achieved with care. Example ---

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

事实上,你那种什么都不想要做与整个框架体系,也不是协程,听起来像是你需要用一个数学计算也许是主题。

Indeed you sort of want nothing to do with the whole frame system, nor coroutines, sounds like you need a thread perhaps with a math calculation.

只是重复相同的点,

public class TaskScheduler : MonoBehaviour

请注意,协同程序非常简单

Note that coroutines very simply

一个协程什么比这更多:

a "coroutine" is nothing more than this:

这就是它。如你所知,在游戏引擎的环境给你一个每一帧......的理念运行的循环。

That's all it is. As you know, the game engine environment gives you a "each frame..." concept run loop.

让我们说无论出于何种原因(说..移动对象,动画怪物),你想要做的事每帧。共有访问统一的能力两个方面

Let's say for whatever reason (say .. moving an object, animating a monster) you want to do something "every frame". There are two ways to access that ability in Unity.

(1)只要使用update()quasifunction其统一为您提供:

(1) Just use the Update() quasifunction which Unity provides for you:

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

管理(2)只要使用协程:

(2) Just use a coroutine:

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)
     }
  }

需要注意的是 - 事实上 - 如果你只要您使用统一的一天多是有经验的程序员,你认识更新()的事情是一般来讲完全傻了,你倾向于只使用自己的协同程序做一些事情每一帧。 (当然,更新()是很方便的只为快速演示或测试代码时什么的。)

Note that - indeed - if you're an experienced programmer as soon as you use Unity for more than a day, you realise the "Update()" thing is generally speaking completely silly, you tend to just use your own coroutine to do something each frame. (Of course, "Update()" is handy just for quick demos or whatever when testing code.)

再次重申,couroutines只是不连接任务或者线程 - 这 - 我猜,当然我可能是错 - 是你在说什么。协同程序只是你如何在统一访问框架体系。对于团结线程,在看向了许多线程池辅助类型的脚本或可用的系统,可方便地之一。

Again to reiterate, couroutines just have no connection to "tasks" or "threads" -- which -- I guess, of course I may be wrong -- is what you're getting at. Coroutines are simply how you access the "frame system" in Unity. For threading in unity, look in to one of the many threading-pool-helper type scripts or systems available, which are convenient.

这篇关于什么是嵌套协同程序生成的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆