Есть ли разница в использовании Icon и Bitmap?
Я отлаживал утечки ресурсов в своем приложении и создал тестовое приложение для проверки утечек объектов GDI. В OnPaint я создаю новые иконки и новые растровые изображения, не выбрасывая их. После этого я проверяю увеличение объектов GDi в диспетчере задач для каждого из случаев. Однако, если я продолжу перерисовывать главное окно своего приложения, число объектов GDI увеличивается для значков, но для растровых изображений не происходит никаких изменений. Есть ли какая-то особая причина, почему значки не очищаются так же, как растровые изображения?
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// 1. icon increases number of GDI objects used by this app during repaint.
//var icon = Resources.TestIcon;
//e.Graphics.DrawIcon(icon, 0, 0);
// 2. bitmap doesn't seem to have any impact (only 1 GDI object)
//var image = Resources.TestImage;
//e.Graphics.DrawImage(image, 0, 0);
}
}
Результат испытаний:
- Нет иконок и растровых изображений - 30 объектов GDI
- С растровыми изображениями - 31 объект GDI, число не меняется.
- С иконками - 31, а затем число увеличивается, если вы перекрасите окно.
1 ответ
Я считаю, что вы должны заботиться о иконах вручную. Я немного искал и обнаружил, что GC заботится о растровых изображениях, но не о иконках. Формы иногда сохраняют свою собственную копию значков (я не уверен почему). Способ размещения значков можно найти здесь: http://dotnetfacts.blogspot.com/2008/03/things-you-must-dispose.html
[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);
private void GetHicon_Example(PaintEventArgs e)
{
// Create a Bitmap object from an image file.
Bitmap myBitmap = new Bitmap(@"c:\FakePhoto.jpg");
// Draw myBitmap to the screen.
e.Graphics.DrawImage(myBitmap, 0, 0);
// Get an Hicon for myBitmap.
IntPtr Hicon = myBitmap.GetHicon();
// Create a new icon from the handle.
Icon newIcon = Icon.FromHandle(Hicon);
// Set the form Icon attribute to the new icon.
this.Icon = newIcon;
// Destroy the Icon, since the form creates
// its own copy of the icon.
DestroyIcon(newIcon.Handle);
}