首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#重用IEnumerator而不实现IEnumerator

C#重用IEnumerator而不实现IEnumerator
EN

Stack Overflow用户
提问于 2019-07-01 05:55:01
回答 1查看 451关注 0票数 0

在这种情况下,它触发GC每一个帧。

我知道IEnumerator是句法糖,当生成IEnumerator函数时,它将创建一个新的对象。有办法保留IEnumrator并重用它吗!?我不想直接实现IEnumerator,因为它更复杂。

代码语言:javascript
复制
[ContextMenu("CoroutineGCTest2")]
public void CoroutineGCTest2()
{
    Debug.LogFormat("[CoroutineMemoryTest.CoroutineGCTest2]");
    StartCoroutine(GCTest());
}

struct ForGC
{
    int a;
    int b;
    int c;
    int d;
}

IEnumerator GCTest()
{
    while (true)
    {
        yield return GC(new ForGC());
    }
}

IEnumerator GC(ForGC g)
{
    yield return null;
}

通过实现WaitForSecondsRealtime重用方式实现IEnumerator

代码语言:javascript
复制
IEnumerator GCTest()
{
    //cache it
    WaitForSecondsRealtime wait = new WaitForSecondsRealtime(1f); ;
    while (true)
    {
        yield return wait;
        Debug.LogFormat("wait 1 sec");
        wait.Reuse(2f);
        yield return wait;
        Debug.LogFormat("wait 2 sec");
        //yield return GC();
    }
}

public class WaitForSecondsRealtime : CustomYieldInstruction
{
    public float waitTime { get; set; }
    float m_WaitUntilTime = -1;

    public override bool keepWaiting
    {
        get
        {
            if (m_WaitUntilTime < 0)
            {
                m_WaitUntilTime = Time.realtimeSinceStartup + waitTime;
            }

            bool wait = Time.realtimeSinceStartup < m_WaitUntilTime;
            if (!wait)
            {
                // Reset so it can be reused.
                m_WaitUntilTime = -1;
            }
            return wait;
        }
    }

    public WaitForSecondsRealtime(float time)
    {
        waitTime = time;
    }

    public void Reuse(float time)
    {
        m_WaitUntilTime = -1;
        waitTime = time;
    }
}

但更复杂..。

EN

回答 1

Stack Overflow用户

发布于 2021-06-03 10:11:34

不能重用IEnumerator函数。它是单向的,一次性的对象。IEnumerator有Reset函数,但在这种情况下不能使用。

代码语言:javascript
复制
IEnumerator GCTest()
{
    // An attempt to cache and reuse IEnumerator function
    var e = GC(new ForGC());
    while (true)
    {
        yield return e;
        e.Reset( ); // System.NotSupportedException: Specified method is not supported.
    }
}

那么现在呢?

  • 重构GC()函数,使其可以工作,而不必是IEnumerator函数。消除了IEnumerator和yield return的需求。
    • 必须有一些不使用IEnumerator的替代实现,例如使用Update循环、状态和计时器来实现相同的代码效果。
    • 实际上,IEnumerator函数在内部也被编译器魔术分解了,就像这样。(因为OP在第一行上发布了链接)

  • 创建一个实现IEnumerator的对象来完成这项工作。(“行动纲领”说这很复杂)
  • 或者使用新的框架,它可以以更轻的加权方式运行协同线。参见MicroCoroutine.一节中的https://github.com/neuecc/UniRx
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56830593

复制
相关文章

相似问题

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