2012-06-06 15 views
6

Ich habe einen Thread, der kontinuierlich Bitmaps generiert und einen Screenshot von einem anderen Programmfenster erstellt. Jetzt habe ich eine PictureBox auf meinem Formular, und das wird ständig mit den erzeugten Bitmaps aktualisiert. Hier ist der Code, den ich in dem Thread:Kontinuierliche Erstellung von Bitmaps führt zu Speicherverlust

 Bitmap bitmap = null; 

     while (true) 
     { 
      if (listBoxIndex != -1) 
      { 
       Rectangle rect = windowRects[listBoxIndex]; 
       bitmap = new Bitmap(rect.Width, rect.Height); 
       Graphics g = Graphics.FromImage(bitmap); 
       IntPtr hdc = g.GetHdc(); 
       PrintWindow(windows[listBoxIndex], hdc, 0); 
       pictureBox1.Image = bitmap; 
       g.ReleaseHdc(hdc); 
      } 
     } 

Wie man sehen kann, führt dies zu einem Speicherverlust, wegen der ständigen Aufruf an neue Bitmap (rect.Width, rect.Height). Ich habe versucht, "bitmap.Dispose()" am Ende der While-Schleife hinzuzufügen, aber das führt dazu, dass auch das imageBox-Bild entsorgt wird, wodurch ein riesiges rotes X anstelle des eigentlichen Bildes entsteht. Gibt es eine Möglichkeit, über "Bitmap" zu verfügen, ohne das imageBox-Bild zu entsorgen?

Antwort

10

Sie "lecken" auch das Graphics-Objekt. Versuchen Sie folgendes:

while (true) 
    { 
     if (listBoxIndex != -1) 
     { 
      Rectangle rect = windowRects[listBoxIndex]; 
      Bitmap bitmap = new Bitmap(rect.Width, rect.Height); 
      using (Graphics g = Graphics.FromImage(bitmap)) 
      { 
       IntPtr hdc = g.GetHdc(); 
       try 
       { 
        PrintWindow(windows[listBoxIndex], hdc, 0); 
       } 
       finally 
       { 
        g.ReleaseHdc(hdc); 
       } 
      } 
      if (pictureBox1.Image != null) 
      { 
       pictureBox1.Image.Dispose(); 
      } 
      pictureBox1.Image = bitmap; 
     } 
    } 
+0

Oh, das ist richtig. Wie ist mir das Keyword using entgangen? Ich habe meinen Code geändert. Vielen Dank! – user1440308

+0

'using' die Bitmap wird es entsorgen, nachdem Sie es Ihrer' PictureBox' zugewiesen haben, was dazu führt, dass die Bitmap überhaupt nicht zugänglich wird. Sie müssen die Bitmap für die Dauer der Anzeige auf der "PictureBox" am Leben erhalten. – Lucero

+0

@ XmenW.K. Was genau ist nicht wahr? 'Image.Dispose()' gibt den nativen Bildzeiger frei, Sie können die Quelle selbst überprüfen. – Lucero

1

Das beantwortet Beispiel hat ein Leck mit Grafiken g nach g.ReleaseHdc(..);

Erinnern Sie sich die Grafik variable

wie zum Beispiel dipose:

g.Dispose(); 
Verwandte Themen