简体   繁体   English

在OnPaint中使用Winforms Frameratelock?

[英]Winforms Frameratelock in OnPaint?

I'm currently trying to polish my application and improve it's performance. 我目前正在尝试完善我的应用程序并改善其性能。 Basically, it's an advanced Graph- class. 基本上,它是一个高级GraphClass。 It draws a few lines and refreshes them. 它画了一些线并刷新它们。

After fixing a few slow points, I wanted to benchmark my result. 修正了一些慢点之后,我想对我的结果进行基准测试。 My drawing was stuck at ~65 FPS (which is perfect but I'm benchmarking). 我的绘图卡在〜65 FPS(这是完美的,但我正在进行基准测试)。 I Invalidate my object in a timer (set to 1 ms) and redraw my stuff using the protected override void OnPaint -"way". 我使计时器中的对象无效(设置为1 ms),然后使用受保护的覆盖无效OnPaint-“ way”重绘我的东西。

After that, I put the Invalidate() into the protected override void OnPaint. 之后,我将Invalidate()放入受保护的重写void OnPaint中。 The FPS was set to a few thousand afterwards. 之后将FPS设置为数千。 But using that method will result in an empty screen. 但是使用该方法将导致屏幕空白。

My question is: Is that issue done on purpose? 我的问题是:这个问题是故意做到的吗? That would make sense as anything higher than your screen refreshrate is wasted power. 这是有道理的,因为任何高于屏幕刷新率的东西都是浪费的功率。 But I'd like to disable that "lock" for my benchmarking. 但是我想为基准测试禁用该“锁定”。

Sample code: 样例代码:

//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++;
    }

Thanks 谢谢

~Steve 〜史蒂夫

My drawing was stuck at ~65 FPS 我的绘图卡在〜65 FPS

Yes, that's normal. 是的,那很正常。 You are measuring the operating system's clock interrupt rate. 您正在测量操作系统的时钟中断率。 It ticks 64 times per second on most Windows machines. 在大多数Windows计算机上,它每秒滴答64次。 A timer cannot go faster than that, the minimum useful value for the Interval property is 15. Setting it to 1 has no effect, it still only ticks once every 15.625 msec. 计时器的运行速度不能超过此速度,Interval属性的最小有用值为15。将其设置为1无效,但仍每15.625毫秒仅滴答一次。

You can actually increase the interrupt rate and make the resolution of a timer better. 实际上,您可以提高中断率并提高计时器的分辨率。 You'd have to pinvoke timeBeginPeriod() . 您必须要调用timeBeginPeriod() That's however pretty pointless, a human cannot observe the difference. 但是,这毫无意义,人类无法观察到差异。 The battery on your user's laptop however will, it drains a lot faster. 但是,用户笔记本电脑上的电池会更快地耗尽电量。

The smart thing to do here is to use a practical update rate. 在这里要做的聪明的事情是使用实际的更新率。 Human eyes go up to about 20 frames per second after which it just turns into a blur. 人眼每秒可拍摄约20帧,之后便变成模糊。 Or looks smooth, depending on what kind of updating you are doing. 或者看起来很平滑,具体取决于您正在执行的更新类型。 Something that's taken advantage of in the movie theater, it updates at 24 fps. 在电影院中利用的东西,它以24 fps的速度更新。 So practical Interval property values are a bit below a multiple of the expected clock interrupt rate. 因此,实用的“间隔”属性值比预期的时钟中断率的倍数低一些。 Which are 2 x 15.625 = 31 msec or 32 fps. 这是2 x 15.625 = 31毫秒或32 fps。 And 3 x 15.625 = 46 msec or 21 fps. 3 x 15.625 = 46毫秒或21 fps。 You don't want to arbitrarily make these numbers smaller, your program won't have consistent update rates on different machines if you do that. 您不想随意减小这些数字,如果这样做,您的程序将在不同的计算机上没有一致的更新速率。

You only need to optimize your code if your painting code cannot keep up with that rate. 仅当绘画代码无法跟上该速度时,才需要优化代码。 Nothing actually goes wrong on, say, a slow machine as long as you use a timer and don't try to force the rate up like you've been doing. 只要您使用计时器,并且不要像往常一样试图提高速率,那么一台慢速机器实际上并没有出错。 The timer's Tick event will simply be delayed and your effective FPS will now be set by the speed of your painting code. 计时器的“滴答”事件将被简单地延迟,您的有效FPS现在将通过绘画代码的速度来设置。

You avoid animation sequences taking longer on slow machines by calculating the actual elapsed time instead of relying on the frame number. 通过计算实际经过的时间而不是依赖帧号,可以避免动画序列在慢速计算机上花费更长的时间。 Either from Environment.TickCount or DateTime.UtcNow, they update at the clock interrupt rate as well. 无论是从Environment.TickCount还是DateTime.UtcNow,它们都以时钟中断速率进行更新。 Stopwatch is okay too, it is overkill. 秒表也可以,这太过分了。 The animation will then take just as long as on a fast machine, it will just look coarser. 动画将花费与在快速计算机上一样长的时间,它看起来会更粗糙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM