Frage

Ich bin ein Newby in C #. Ich muss immer wieder ein GUI-Bildfeld in einem Worker-Thread aktualisieren. Das Bild wird von einer Kamera Polling ein Fahrer mit einem GetImage Verfahren erworben, die das Bild retrives angezeigt werden. Selbst wenn ich die Bitmap-using-Direktive „using“ und explizit aufrufen G.C zuweisen, scheint Speicher nie freigegeben werden.

Der Worker-Thread ist so etwas wie folgt aus:

   while (true)
    {
        // request image with IR signal values (array of UInt16)
        image = axLVCam.GetImage(0);
        lut = axLVCam.GetLUT(1);
        DrawPicture(image, lut);
        //GC.Collect();

    }

Während die DrawPicture Methode ist so etwas wie

   public void DrawPicture(object image, object lut)
{

  [...]

    // We have an image - cast it to proper type
    System.UInt16[,] im = image as System.UInt16[,];
    float[] lutTempConversion = lut as float[];

    int lngWidthIrImage = im.GetLength(0);
    int lngHeightIrImage = im.GetLength(1);

    using (Bitmap bmp = new Bitmap(lngWidthIrImage, lngHeightIrImage)) {

      [...many operation on bitmap pixel...]

        // Bitmap is ready - update image control

        //SetControlPropertyThreadSafe(tempTxtBox, "Text", string.Format("{0:0.#}", lutTempConversion[im[160, 100]]));

        //tempTxtBox.Text = string.Format("{0:00000}", im[160, 100]);
        //System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
        pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
    }
}

Probleme stellen sich mit dem

  

pic.Image = System.Drawing.Image.FromHbitmap (bmp.GetHbitmap ());

In der Tat, dass die Code-Zeile zu kommentieren, Müllabfuhr funktioniert, wie es tun würde. Besser, das Problem scheint zu sein

  

System.Drawing.Image.FromHbitmap (bmp.GetHbitmap ())

Jede Beratung dieses Speicherleck zu lösen?

Vielen Dank!

War es hilfreich?

Lösung

Image implementiert IDisposable, so dass Sie Dispose auf jeder Image Instanz aufrufen sollte, dass Sie erstellen, wenn es nicht mehr benötigt wird. Sie könnten versuchen, diese Zeile im Code zu ersetzen:

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

Mit diesem:

if (pic.Image != null)
{
    pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

Dies wird das vorherige Bild (falls vorhanden), bevor die neuen entsorgen zugeordnet ist.

Andere Tipps

Die Sache ist, sind Sie ein GDI-Bitmap von bmp mit GetHbitmap machen, die nach Msdn:

  

Sie sind verantwortlich für den Aufruf der   GDI DeleteObject Verfahren die frei   Speicher, der von dem Objekt GDI-Bitmap verwendet wird.

Dann wird die FromHbitmap Methode macht eine Kopie der GDI-Bitmap; so können Sie die eingehende GDI-Bitmap lassen Sie die GDI DeleteObject-Methode unmittelbar nach dem neuen Image zu schaffen.

Also im Grunde möchte ich hinzufügen:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

IntPtr gdiBitmap = bmp.GetHbitmap();

// Release the copied GDI bitmap
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = System.Drawing.Image.FromHbitmap(gdiBitmap);

// Release the current GDI bitmap
DeleteObject(gdiBitmap);

Ich bin nicht sicher, ob Sie den GDI-Bitmap eine Art von Transformation durchzuführen. Falls Sie Sie nicht nur ordnen Sie die Bitmap in die Bild-Eigenschaft des PictureBox kann, und ignorieren die frühere Lösung:

// Since we're not using unmanaged resources anymore, explicitly disposing 
// the Image only results in more immediate garbage collection, there wouldn't 
// actually be a memory leak if you forget to dispose.
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = bmp;

Es gibt mehrere Möglichkeiten, um ein Bild von pbox zu lösen. Ich empfehle dringend, die Art und Weise, dass nicht verwendet pbox.Image = Image.FromFile... ist. Wenn Sie Filestream nicht und Sie wollen es lesen, die aus der Benutzung BitMap Klassendatei. Wie folgt aus:

Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.

... und dann wollen Sie die Bilddatei bmp.Dispose();
freizugeben Jetzt können Sie löschen, verschieben oder was auch immer Sie wollen in die Datei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top