以并行方式生成数组的简单方法

时间:2016-09-22 11:58:46

标签: c# unity3d coroutine

较新版本的C#有async / await。但在Unity中只有yield如何实现我可以并行yield的方法?

与Javascript中的Promise.all([])类似,我们并不关心哪一个首先完成,我们只关心它们何时完成。

为了给出更多上下文,假设你正在设计一个程序化地形生成器,用于生成 in chunks ;并且您已使用ThreadPool设置要生成的每个块,然后提供返回IEnumerator的API:

IEnumerator GenerateChunk() {
  // procedural generation
  // queue itself onto a ThreadPool
  // when done, yield
}

IEnumerator GenerateChunks() {
  for (int i = 0; i < chunks.Length; i++) {
    yield return chunks[i].GenerateChunk();
  }
}

void GenerateMap() {
  StartCoroutine(GenerateChunks());
}

我们可以做yield IEnumerator[]吗?

更新:我不确定我是否表达了清楚。基本上我想立即启动所有GenerateChunk,并允许它们尽快完成,而不是一个接一个地产生。

我的代码是否已经这样做了,还是我还需要其他东西?

2 个答案:

答案 0 :(得分:1)

yield return StartCoroutine(chunks[i].GenerateChunk());

答案 1 :(得分:1)

我读了你的问题,阅读了你留下的答案和评论,我相信你了解协程如何运作。

Coroutine不会并行运行。它将按顺序运行您的代码,同时在同一Thread

中运行
  

更新:我不确定我是否表达了清楚。基本上我想立即启动所有GenerateChunk,并允许它们完成   尽可能快,而不是一个接一个地屈服。

     

我的代码是否已经这样做了,还是我还需要其他东西?

即可。如果要像位置一样快速调用该函数,则不应在每个函数后yield。每次yield,您都在等待一帧。我是否甚至提到你甚至没有正确调用GenerateChunk功能?仔细看,你也会注意到。 GenerateChunk函数是一个协程函数,必须使用StartCoroutine()调用。

在for循环中启动GenerateChunk后,会产生效果。你应该只在for循环函数之外产生或破坏。您可以在代码和下面的代码之间进行简单的性能测试,以使用Stopwatch验证这一点。

IEnumerator GenerateChunk()
{
    // procedural generation
    // queue itself onto a ThreadPool
    // when done, yield
}

IEnumerator GenerateChunks()
{
    for (int i = 0; i < chunks.Length; i++)
    {
        StartCoroutine(GenerateChunk());
    }
    yield break;
    //Or yield return null;
}