C# 有多少任务太多了

C# 有多少任务太多了,c#,C#,我正在做一个太空船射击游戏。在游戏中,我在不同的任务中运行缓慢移动的导弹 Task t4 = new Task(() => fireShipCannons()); 他们做的不多;只需在屏幕上移动一个小位图。通常它是一个包含30次迭代的for循环。问题是,时间不早了,有些任务似乎比其他任务更重要。我还需要注意的是,为了控制导弹的速度,我正在使用Thread.Sleep(100)。由于速度减慢,该方法将运行几秒钟 我正在使用c#、.net、Windows窗体应用程序 我花了几个小时思考如何改

我正在做一个太空船射击游戏。在游戏中,我在不同的任务中运行缓慢移动的导弹

Task t4 = new Task(() => fireShipCannons());
他们做的不多;只需在屏幕上移动一个小位图。通常它是一个包含30次迭代的for循环。问题是,时间不早了,有些任务似乎比其他任务更重要。我还需要注意的是,为了控制导弹的速度,我正在使用Thread.Sleep(100)。由于速度减慢,该方法将运行几秒钟

我正在使用c#、.net、Windows窗体应用程序


我花了几个小时思考如何改写这个,我认为它的措辞是正确的。我遇到的问题很广泛;因此,是的,问题可能有点宽泛。我得到了一个很好的答案!这不表示问题问得正确吗?

这取决于机器及其支持的线程数。另一方面,我不认为使用Thread.Sleep是一种很好的做法,为什么不改变对象每毫秒移动的距离(以像素为单位)?

这取决于机器及其支持的线程数。另一方面,我不认为使用Thread.Sleep是一种很好的做法,为什么不改变物体每毫秒移动的距离(以像素为单位)?

既然你已经在使用
任务
s(好),你可以简单地制作它们并使用
等待任务。延迟(时间)


最后,最好不要对每个项目符号都使用新的调用来敲打draw函数,而是将所有项目符号/更改合并到一个渲染函数中,该函数计算所有更改并一次性发送。但这取决于绘图函数本身的实现方式。

因为您已经在使用
任务
s(好),您只需制作它们并使用
等待任务。延迟(时间)


最后,最好不要对每个项目符号都使用新的调用来敲打draw函数,而是将所有项目符号/更改合并到一个渲染函数中,该函数计算所有更改并一次性发送。但这取决于绘图函数本身是如何实现的。

这不能很好地扩展到为游戏制作动画,而且
任务中也没有足够的精度。延迟
@Servy
任务。延迟
线程.Sleep
一样精确。两者都基于系统时钟,在实践中精确到15毫秒。这个解决方案至少不会为每一颗子弹绑上一根线。你可以添加大量额外的逻辑来计算下一步的睡眠时间、我们睡眠的时间(如果超过100毫秒,则跳过迭代)等等。但这超出了这个答案的范围。你说得很对,
线程。睡眠也不适合计时动画;OP提到了他的一个主要问题,那就是时间安排都被取消了,这是他需要解决的核心问题,而你没有解决。不为每一个被设置动画的项目捆绑一个完整的线程确实要好得多,但这并不能改变这样一个事实,即虽然更好,但仍然远远不够。@Servy可能无法缩放的部分是锤击
drawBitmap(i)
用于每个对象,但是
任务
s应该对此没有问题,即使同时运行10.000个对象。如果你想建议OP彻底检修他的设计,请随意写一个这样做的答案,我只是演示如何解决他当前的问题。此外,即使是重新改装的设计也可以从使用上述技术中受益,使用
等待任务。延迟
。有趣的是,15毫秒的准确度达到了60帧/秒,对于大多数游戏来说已经足够了。因此,不是
drawBitmap(i)将其替换为
updatealBitMap()。这不能很好地扩展到为游戏制作动画,在
任务中也没有足够的精度。延迟
@Servy
任务。延迟
线程.睡眠
一样精确。两者都基于系统时钟,在实践中精确到15毫秒。这个解决方案至少不会为每一颗子弹绑上一根线。你可以添加大量额外的逻辑来计算下一步的睡眠时间、我们睡眠的时间(如果超过100毫秒,则跳过迭代)等等。但这超出了这个答案的范围。你说得很对,
线程。睡眠也不适合计时动画;OP提到了他的一个主要问题,那就是时间安排都被取消了,这是他需要解决的核心问题,而你没有解决。不为每一个被设置动画的项目捆绑一个完整的线程确实要好得多,但这并不能改变这样一个事实,即虽然更好,但仍然远远不够。@Servy可能无法缩放的部分是锤击
drawBitmap(i)
用于每个对象,但是
任务
s应该对此没有问题,即使同时运行10.000个对象。如果你想建议OP彻底检修他的设计,请随意写一个这样做的答案,我只是演示如何解决他当前的问题。此外,即使是重新改装的设计也可以从使用上述技术中受益,使用
等待任务。延迟
。有趣的是,15毫秒的准确度达到了60帧/秒,对于大多数游戏来说已经足够了。因此,不是
drawBitmap(i)将其替换为
updatealBitMap()。你不应该为游戏中的每个对象增加一个任务。实际上,通常只有一个循环来控制游戏中的所有变化。为了简单起见,循环看起来像:while(isGameRunning){Update(DateTime.UtcNow);Render();}您应该知道游戏中每个对象的实际速度向量,并在Update方法中计算新位置。然后,Render方法将绘制当前状态,无论自上次更新以来经过了多少时间,都是di
    async Task fireShipCannons(CancellationToken ct)
    {
        for (int i = 0; i < distance; i++) {
           await Task.Delay(100, ct);
           drawBitmap(i);
        }
    }
    async Task fireShipCannons(CancellationToken ct)
    {
        var start = DateTime.Now;
        while (bullet.isOnscreen) {
           drawBitmap(bullet);
           var sleep = (start.Add(TimeSpan.FromMilliseconds(100.0)) - DateTime.Now);
           if (sleep.Milliseconds > 0) {
               Task.Delay(sleep, ct);
           }
           iter = (int)((DateTime.Now - start).TotalMilliseconds / 100 + 0.5);
           bullet.moveSteps(iter); // move it iter steps.
           var start = start.AddMilliseconds(100 * it);
       }
    }