双缓冲在高负载时抛出异常

时间:2015-08-27 07:37:36

标签: c# winforms out-of-memory doublebuffered

我正在测试我的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)

0 个答案:

没有答案