我正在测试我的Windows窗体用户控件。当应用程序负载很高时(比如应用程序需要超过1 GB),它会抛出内存不足或参数无效异常。
以下是使用缓冲区
绘制控件的代码protected override void OnPaint(PaintEventArgs e)
{
if (m_buffer == null || m_Redraw)
{
if (m_buffer != null)
m_buffer.Dispose();
m_buffer = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(m_buffer))
{
DrawUserControl(g, ClientRectangle);
}
m_Redraw= false;
}
e.Graphics.DrawImage(m_buffer, Point.Empty);
base.OnPaint(e);
}
内存不足异常发生在e.Graphics.DrawImage(m_buffer, Point.Empty);
new Bitmap(Width, Height);
注意:仅当应用程序负载超过1 GB时才会发生异常(例如 1.5 GB,2GB RAM)。
没有缓冲的绘画控件不会抛出任何异常但会导致闪烁效果。这是没有缓冲的代码
protected override void OnPaint(PaintEventArgs e)
{
this.SuspendLayout();
DrawUserControl(e.Graphics, ClientRectangle);
this.ResumeLayout();
base.OnPaint(e);
}
我希望我的控件在高负载下呈现而不会闪烁。由于我的控制,我不希望应用程序中断。请分享您的建议
与缓冲相关的修改:
1)在所有绘画事件期间不会创建缓冲区图像。它将在第一次创建,如果需要重新绘制控件。否则,将在控件上绘制现有缓冲区图像。这避免了不必要的重新绘制控件
2)如果需要重新绘制控件,将使用新的位图,因为现有缓冲区图像的大小和控件的当前大小可能会有所不同。即使我使用现有图像,参数无效抛出异常
尝试使用BufferedGraphicsContext
根据@ taffer的回答,我尝试使用BufferedGraphicsContext
。它还会抛出内存不足异常。我在下面发布了堆栈跟踪
System.ComponentModel.Win32Exception(0x80004005):存储空间不足 可用于处理此命令 在System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal,Int32 ulWidth,Int32 ulHeight,IntPtr& ppvBits)
在System.Drawing.BufferedGraphicsContext.CreateBuffer(IntPtr src, Int32 offsetX,Int32 offsetY,Int32 width,Int32 height)
在System.Drawing.BufferedGraphicsContext.AllocBuffer(Graphics targetGraphics,IntPtr targetDC,Rectangle targetRectangle)
在 System.Drawing.BufferedGraphicsContext.AllocBufferInTempManager(图形 targetGraphics,IntPtr targetDC,Rectangle targetRectangle) 在System.Drawing.BufferedGraphicsContext.Allocate(Graphics targetGraphics,Rectangle targetRectangle)