Удалить обработчик, когда пользовательский контроль утилизирует

Какой из них правильный?

Вот этот:

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
        components.Dispose();
    }
    base.Dispose(disposing);
}

ИЛИ ЖЕ

Вот этот:

~ ctlRemoteBuildContent1()
{
    this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
}

Я пытался переключить эти 2 функции. Когда я выполнил UserControl, он не попал в строку переключения:/

3 ответа

Решение

Если вы выполняете очистку в деструкторе, нет никакой гарантии относительно того, когда деструктор будет запущен. Объекты с деструктором также требуют больше работы для сборщика мусора. Поэтому желательно реализовать IDisposable, который является вашим первым примером.

Обратите внимание, что ваш фрагмент кода не полностью реализует рекомендованный шаблон IDisposable. Пожалуйста, смотрите эту статью для хорошего и полного объяснения:

http://www.csharphelp.com/2010/02/c-garbage-collecting-destructors-versus-dispose/

В вашем фрагменте кода, если по какой-то причине components имеет значение null, вы не удалили бы обработчик событий. Нулевая проверка для components должно быть сделано только для защиты components.Dispose() вызов.

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
        if (components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose(disposing);
}

Второй бит кода вызывается финализатором, что означает, что вы не сможете определить, когда он вызывается (зависит от того, когда работает сборщик мусора). В идеале вы хотите освободить свои ресурсы как можно скорее, обычно в Dispose(). Так что используйте шаблон утилизации здесь.

Почему вы хотите отменить это событие здесь? Что это содержит?

Какой из них правильный?

Немного неприятный ответ "оба";-) ...

В идеале вы хотите, чтобы приведение в порядок происходило в методе Dispose, чтобы его можно было выполнить как можно скорее, но в некоторых ситуациях важно также вызывать код очистки, вызываемый из деструктора, в качестве резервной копии в случае использования объекта без утилизации (... я думаю, это зависит от того, насколько вероятно, вы думаете, что это может быть!?)

Шаблон dispose (упомянутый в других ответах) предоставляет способ реализовать это без дублирования кода между dispose и destructor, а с помощью GC.SupressFinalize гарантирует, что сборка мусора объекта не будет задерживаться без необходимости, если приведена в порядок сделанный.

Другие вопросы по тегам