Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET/GDI+;_C#_.net_Animation_Cpu_Stopwatch - Fatal编程技术网

C# 在.NET/GDI+;

C# 在.NET/GDI+;,c#,.net,animation,cpu,stopwatch,C#,.net,Animation,Cpu,Stopwatch,我在GDI+中制作平滑动画时遇到问题。我从谷歌搜索中了解到的问题是,在多核处理器上的.NET中,存在一些时钟滴答作响的bug。以下是我所做工作的简化版本: class Animation { System.Diagnostics.Stopwatch sw = new Stopwatch(); float AnimationTime = 1000; //time it takes the animation to complete public bool IsComplete {

我在GDI+中制作平滑动画时遇到问题。我从谷歌搜索中了解到的问题是,在多核处理器上的.NET中,存在一些时钟滴答作响的bug。以下是我所做工作的简化版本:

class Animation
{
  System.Diagnostics.Stopwatch sw = new Stopwatch();
  float AnimationTime = 1000; //time it takes the animation to complete

  public bool IsComplete
  { get { return sw.ElapsedMilliseconds > AnimationTime; } }

  public void StartAnimation()
  {
     sw.Reset();
     sw.Start();
  }

  public void DoFrame()
  {
     float PercentComplete = (float)sw.ElapsedMilliseconds / AnimationTime;
     //draw the animation based on PercentComplete
  }
}
DoFrame()的调用方式如下:

Animation.Start();
do
{
  Animation.DoFrame();
  Application.DoEvents();
} while (!Animation.IsComplete);
问题是,动画在大约15帧内非常平滑,然后它会猛拉,它实际上会向后移动(sw.elapsedmillesons给出的值小于上一个查询)。这是非常恼人的,它破坏了我原本平滑的动画,即使在Core2Duo上看起来也很棒(尽管微软说这是一个多核bug)。我有一个i7,动画是平滑的,除了每秒2-3帧看起来“急促”

我知道这是一个已知的问题,微软将其归咎于处理器,所以我的问题是,有人知道这方面的解决方案吗?我试着用卡尔曼滤波器,它有点效果。我希望有一个“正确”的解决方案

哦,b.t.w.我试着用DateTime代替秒表,得到了同样的结果

我还尝试:

double PercentComplete = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency * 1000 / AnimationTime

它给了我同样的结果。

这可能与调用
DoFrame()
的方式有关。使用以下基于windows窗体/GDI+的算法,您应该始终获得非常平滑的动画:

const double desiredFps = 500.0;
long ticks1 = 0;
var interval = Stopwatch.Frequency / desiredFps;
while (true)
{
    Application.DoEvents();
    var ticks2 = Stopwatch.GetTimestamp();
    if (ticks2 >= ticks1 + interval)
    {
        ticks1 = Stopwatch.GetTimestamp();

        // do the drawing here
    }
}

DoFrame()每秒从主线程调用40-60次。在它完成之前不会再调用它。你能知道实际的代码吗?这可能是相关的。您使用的是
System.Timers.Timer
还是
System.Windows.Forms.Timer
或完全不同的东西?我没有使用System.Timers.Timer。我甚至不知道那门课。我用的是秒表,我也试过DateTime,两者的结果都一样。我确信实际代码与此无关,因为它在Core Duo处理器上看起来非常完美。请尝试使用计时器触发
DoFrame
。GDI+中的动画通常就是这样做的。或者问题可能是因为您使用了float?
Application.DoEvents()在循环中…为什么?DoEvents来自主线程。。。动画发生在不同的线程上。。。我会试试你的方法。控制帧率似乎确实有帮助,只要系统能够比期望的帧率做得更好。恒定的抖动消失了,虽然有新的间歇性抖动,但我认为我的抖动与另一个线程上发生的事情有关。谢谢