在OnPaint中Winforms Frameratelock?

时间:2013-08-10 12:56:52

标签: c# winforms onpaint

我正在尝试改进我的应用程序并提高它的性能。 基本上,它是一个高级的Graph-class。它绘制了几行并刷新它们。

在确定了几个慢点之后,我想对我的结果进行基准测试。 我的绘图卡在~65 FPS(这是完美的,但我是基准测试)。 我在一个计时器(设置为1毫秒)中使我的对象无效,并使用受保护的覆盖void OnPaint重新绘制我的东西 - “方式”。

之后,我将Invalidate()放入受保护的覆盖void OnPaint中。事后FPS设定为几千。但是使用该方法会导致屏幕空白。

我的问题是:这个问题是故意的吗?这是有道理的,因为高于屏幕刷新率的任何东西都是浪费的力量。但我想为我的基准测试禁用“锁定”。

示例代码:

//Timer to refresh
private void timer1_Tick(object sender, EventArgs e)
    {
        Invalidate();
    }

private DateTime date = DateTime.UtcNow;
    private long times = 0;
    protected override void OnPaint(PaintEventArgs e)
    {

        base.OnPaint(e);

        //Drawing
        e.Graphics.DrawLine(new Pen(Brushes.Black), 50, 50, Width - 100, Height - 100);

        //Required to tell me the framerate
        if ((DateTime.UtcNow - date).Seconds > 1)
        {
            date = DateTime.UtcNow;
            Debug.WriteLine(times);
            times = 0;
        }

        times++;
    }

由于

〜史蒂夫

1 个答案:

答案 0 :(得分:7)

  

我的绘图停留在~65 FPS

是的,这是正常的。您正在测量操作系统的时钟中断率。在大多数Windows机器上,它每秒运行64次。计时器不能快于此,Interval属性的最小有用值为15.将其设置为1无效,它仍然只能每15.625毫秒滴答一次。

您实际上可以提高中断率并使计时器的分辨率更好。你必须要timeBeginPeriod()。然而,这是毫无意义的,人类无法观察到差异。然而,用户笔记本电脑上的电池会消耗得更快。

这里聪明的做法是使用实用更新率。人眼每秒上升到大约20帧,然后它变成模糊。或者看起来很流畅,具体取决于您正在进行的更新类型。在电影院中被利用的东西,它以24 fps更新。因此实际的Interval属性值略低于预期时钟中断率的倍数。其中2 x 15.625 = 31毫秒或32 fps。并且3 x 15.625 = 46毫秒或21 fps。您不希望随意使这些数字变小,如果您这样做,您的程序将不会在不同的计算机上具有一致的更新速率。

如果您的绘画代码无法跟上该速率,您只需要优化代码。只要你使用计时器并且不试图像你一直那样强迫加速,那么在慢速机器上实际上什么都不会出错。计时器的Tick事件将被延迟,您的有效FPS现在将根据您的绘画代码的速度设置。

通过计算实际经过的时间而不是依赖于帧编号,可以避免动画序列在慢速机器上花费更长时间。从Environment.TickCount或DateTime.UtcNow开始,它们也以时钟中断速率更新。秒表也没问题,这太过分了。然后动画将在快速机器上运行,它看起来会更粗糙。