Есть ли разница в использовании 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);
    }
}

Результат испытаний:

  1. Нет иконок и растровых изображений - 30 объектов GDI
  2. С растровыми изображениями - 31 объект GDI, число не меняется.
  3. С иконками - 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);
}
Другие вопросы по тегам