如何在不阻塞程序的情况下运行while循环?

4

我目前正在使用C#编写程序,需要类似于Unity引擎中的Update方法的东西。基本上是一个循环,在给定的tick速率下一遍又一遍地执行给定的代码。为了重新创建这个功能,我计划只使用while (true)循环,并以某种方式运行它,而不会阻塞我的线程的其余部分。有没有办法做到这一点?我的当前方法看起来像这样。

public void Update(int tickrate)
{
    while (true)
    {
        foreach (IAgent agent in Agents)
        {
            agent.Move();
        }

        Task.Delay(tickrate / 60);
    }
}

1
有几个问题需要解决:Task.Delay 在这里不会起作用,因为它没有被等待。所以,我猜你是在谈论类似于游戏循环的东西?恐怕你需要变得更加复杂才行,尤其是如果你想在(大约)给定的时钟速率下执行它(记住我们不在实时系统中!)。 - Fildor
1
大多数计时器都有可以附加到的事件,因此我不确定您所说的“组合”是什么意思。正如Fildor所提到的,计时器可能存在问题,但如果您的计时器间隔为33ms,并且移动所有代理需要2ms,则您很可能不会遇到问题。 - JonasH
1
使用游戏引擎会很容易,我知道。不幸的是,我正在制作的这个程序将用于模拟我正在构建的一个小传感器的运动。我想要测试许多输入,而不必实际在传感器前挥舞大量灯光,因此我不能真正使用引擎。 :/ @Fildor - Hale Jan
1
啊,原来你并不是在制作游戏。别误会:我并没有说“这行不通”。我只是想说:你需要考虑一些事情。但是Batesias的回答看起来很有前途。 - Fildor
1
嗯,我正在制作一个游戏。只是不是很有趣;D @Fildor - Hale Jan
显示剩余9条评论
1个回答

6
这可能是使用 .Net 6 中的新 PeriodicTimer 的一个很好的用例。
这里有一个 很好的视频解释它
你的游戏循环可以看起来像这样。
public async Task RunGame()
{
    // Create the timer by defining the period.
    // I used a period of 1/60 seconds (which would result in 60 updates per second).
    var timer = new PeriodicTimer(TimeSpan.FromSeconds(1.0/60));
    while (true)
    {
        foreach (IAgent agent in Agents)
        {
            agent.Move();
        }

        // WaitForNextTickAsync waits for the right amount of time
        // by considering the time spent updating the game state.
        await timer.WaitForNextTickAsync(CancellationToken.None);
    }
}

请注意,我使用CancellationToken.None是为了简洁明了。在RunGame方法的参数中传递一个CancellationToken是有意义的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接