I have a custom control in C#. I have noticed that calling Refresh
is much slower than I would like (about 0.1ms), even when I have an empty RePaint
function. Basically, my application processes a grid and, one by one, it refreshes each grid cell. This rather inefficient behavior is by design; when enabled I want to be able to actually see what each step of processing has done, and each step only ends up changing one cell. Toggling double-buffering does not make much difference.
我在C#中有一个自定义控件。我注意到调用Refresh比我想要的慢很多(大约0.1ms),即使我有一个空的RePaint函数。基本上,我的应用程序处理一个网格,并逐个刷新每个网格单元格。这种相当低效的行为是设计的;当启用时,我希望能够实际看到每个处理步骤的内容,并且每个步骤最终只会更改一个单元格。切换双缓冲没有太大区别。
Can anyone offer any advice?
有人可以提供任何建议吗?
Currently, the best improvement I've come up with is to replace my call to Refresh
with a call to Refresh2
. The latter function is an exact copy of Repaint
, except for two lines added to the top, Graphics g = Graphics.FromHwnd(this.Handle); g.Clear(BackColor);
and replacing e.Graphics
with g
. I am suspicious that there is some disadvantage to this, but it does cut the drawing speed in half. Take note that the control I am working with has no subcomponents, so things like validation don't have quite as much concern.
目前,我提出的最好的改进是通过调用Refresh2替换我对Refresh的调用。后一个函数是Repaint的精确副本,除了添加到顶部的两行,Graphics g = Graphics.FromHwnd(this.Handle); g.Clear(背景色);用g代替e.Graphics。我怀疑这有一些不利之处,但确实将绘图速度降低了一半。请注意,我正在使用的控件没有子组件,因此验证之类的问题并没有那么多。
2 个解决方案
#1
Refreshing too much would slow it down as you experienced, try to compress events i.e don't refresh when you get a new grid but set a variable when you need to update, and let a timer check that variable every 1 sec for example and refresh then.
刷新太多会降低你的速度,尝试压缩事件,即当你得到一个新的网格时不刷新,但是当你需要更新时设置一个变量,让一个计时器每1秒检查一次该变量,例如刷新然后。
#2
Is the refresh a automatic recurring event or in response to a user event?
刷新是自动重复发生的事件还是响应用户事件?
In the first case it should be asynchronous (in its own thread). If in response to a user event, then that would also be true in the case that the "refresh" is not critical to the event.
在第一种情况下,它应该是异步的(在它自己的线程中)。如果响应用户事件,那么在“刷新”对事件不重要的情况下也是如此。
If the code that updates the interface is too slow, make sure it is only doing the updating of the interface (it should have data already ready.. which is along the vein of double buffering). If that is not the case, do some logging, find out what is taking too much time.
如果更新接口的代码太慢,请确保它只是更新接口(它应该已经准备好了数据......这是双缓冲的一种方式)。如果不是这样,做一些记录,找出花费太多时间的东西。
If it must get data first, then some lag is expected. If that is unacceptable, then you'll need to have some caching mechanism. You can have the cache automatically updated asynchronously or have it return what's cached, get fresh data, then cause another update.. or something to that effect.
如果它必须首先获得数据,那么预计会有一些滞后。如果这是不可接受的,那么你需要有一些缓存机制。您可以异步自动更新缓存,或者让它返回缓存的内容,获取新数据,然后导致另一次更新......或者其他类似的事情。
#1
Refreshing too much would slow it down as you experienced, try to compress events i.e don't refresh when you get a new grid but set a variable when you need to update, and let a timer check that variable every 1 sec for example and refresh then.
刷新太多会降低你的速度,尝试压缩事件,即当你得到一个新的网格时不刷新,但是当你需要更新时设置一个变量,让一个计时器每1秒检查一次该变量,例如刷新然后。
#2
Is the refresh a automatic recurring event or in response to a user event?
刷新是自动重复发生的事件还是响应用户事件?
In the first case it should be asynchronous (in its own thread). If in response to a user event, then that would also be true in the case that the "refresh" is not critical to the event.
在第一种情况下,它应该是异步的(在它自己的线程中)。如果响应用户事件,那么在“刷新”对事件不重要的情况下也是如此。
If the code that updates the interface is too slow, make sure it is only doing the updating of the interface (it should have data already ready.. which is along the vein of double buffering). If that is not the case, do some logging, find out what is taking too much time.
如果更新接口的代码太慢,请确保它只是更新接口(它应该已经准备好了数据......这是双缓冲的一种方式)。如果不是这样,做一些记录,找出花费太多时间的东西。
If it must get data first, then some lag is expected. If that is unacceptable, then you'll need to have some caching mechanism. You can have the cache automatically updated asynchronously or have it return what's cached, get fresh data, then cause another update.. or something to that effect.
如果它必须首先获得数据,那么预计会有一些滞后。如果这是不可接受的,那么你需要有一些缓存机制。您可以异步自动更新缓存,或者让它返回缓存的内容,获取新数据,然后导致另一次更新......或者其他类似的事情。