проблема освобождения памяти c# picturebox
Я новичок в C#. Я должен неоднократно обновлять поле изображения GUI в рабочем потоке. Изображение, приобретенное с камеры избирательных водитель с метод getimage, что retrives изображение, которое будет отображаться. Даже если я выделяю растровое изображение с помощью директивы "using" и явно вызываю G. C, память, похоже, никогда не освобождается.
рабочий поток выглядит примерно так:
while (true)
{
// request image with IR signal values (array of UInt16)
image = axLVCam.GetImage(0);
lut = axLVCam.GetLUT(1);
DrawPicture(image, lut);
//GC.Collect();
}
в то время как метод DrawPicture-это что-то как
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());
}
}
проблемы возникают с
рис.система визуализации.Рисунок.Изображение.FromHbitmap(bmp.GetHbitmap ());
фактически комментируя эту строку кода, сборка мусора работает так, как она будет. Лучше, проблема, кажется, с
3 ответов
Image
осуществляет IDisposable
, Так что вы должны позвонить Dispose
в каждом Image
экземпляр, который вы создаете, когда он больше не нужен. Вы можете попытаться заменить эту строку в своем коде:
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
С этого:
if (pic.Image != null)
{
pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
это будет утилизировать предыдущее изображение (если таковое имеется) перед назначением нового.
дело в том, что вы делаете растровое изображение GDI bmp
С GetHbitmap, который согласно msdn:
вы несете ответственность за вызов Метод GDI DeleteObject для освобождения память, используемая растровым объектом GDI.
затем метод FromHbitmap создает копию растрового изображения GDI; таким образом, вы можете освободить входящее растровое изображение GDI с помощью метода GDI DeleteObject сразу после создания нового изображения.
Так что в основном я бы добавить:
[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);
Я не уверен, что вам нужно растровое изображение GDI для выполнения какого-то преобразования. Если вы этого не сделаете, вы можете просто назначить растровое изображение свойству Image вашего PictureBox и игнорировать первое решение:
// 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;
существует несколько способов освободить изображение из pbox. Я настоятельно рекомендую способ, что не используйте pbox.Image = Image.FromFile...
. Если вы не используете FileStream и хотите прочитать его из файла, используйте класс BitMap. Вот так:
Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.
... и тогда вы хотите, чтобы освободить файл изображения bmp.Dispose();
Теперь вы можете удалить, переместить или все, что вы хотите в файл.