title: Double buffering throws exception at high load
body: <p>I am testing my windows forms user control. When application load is high (say application takes more than 1 GB), it throws <strong>Out of memory</strong> or <strong>Argument invalid</strong> exceptions.</p>
  
  <p>Here is the code to draw the control with buffer,</p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p>Out of memory exception occurs at <code>e.Graphics.DrawImage(m_buffer, Point.Empty);</code></p>
  
  <p>Argument invalid exception occurs at <code>new Bitmap(Width, Height);</code></p>
  
  <blockquote>
    <p>Note: Exception occurs only if application load is more that 1 GB (say
    1.5 GB with 2GB RAM).</p>
  </blockquote>
  
  <p>Painting control without buffering does not throw any exception but causes flickering effect. Here is code without buffering</p>
  
  <pre><code>protected override void OnPaint(PaintEventArgs e)
  {
       this.SuspendLayout();
       DrawUserControl(e.Graphics, ClientRectangle);
       this.ResumeLayout();
       base.OnPaint(e);
  }
  </code></pre>
  
  <p>I want my control to render without flickering under high load. I don't want the application to break due to my control. Please share your suggestions</p>
  
  <p><strong>Edit related to buffering:</strong></p>
  
  <p>1) Buffer image will not be created during all paint events. It will be created during the first time and if control needs to be repainted. Otherwise, existing buffer image will be drawn on the control. This avoids unwanted repainting of the control</p>
  
  <p>2) If control needs to be repainted, a new bitmap will be used because size of the existing buffer image and current size of the control may vary. Even if I use existing image, <strong>Argument is not valid</strong> exception thrown</p>
  
  <p><strong>Tried using BufferedGraphicsContext</strong></p>
  
  <p>As per @taffer's answer, I tried using <code>BufferedGraphicsContext</code>. It also throws <strong>Out of memory exception</strong>. I'm posting the stack trace below</p>
  
  <blockquote>
    <p>System.ComponentModel.Win32Exception (0x80004005): Not enough storage
    is available to process this command
           at System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc,
    IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr&amp; ppvBits)</p>
    
    <p>at System.Drawing.BufferedGraphicsContext.CreateBuffer(IntPtr src,
    Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)</p>
    
    <p>at System.Drawing.BufferedGraphicsContext.AllocBuffer(Graphics
    targetGraphics, IntPtr targetDC, Rectangle targetRectangle)</p>
    
    <p>at
    System.Drawing.BufferedGraphicsContext.AllocBufferInTempManager(Graphics
    targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
        at System.Drawing.BufferedGraphicsContext.Allocate(Graphics targetGraphics, Rectangle targetRectangle)</p>
  </blockquote>