Когда я должен использовать GC.SuppressFinalize ()?

272
задан 8 revs, 7 users 50% 12 September 2017 в 04:46
поделиться

3 ответа

SuppressFinalize должен только назвать класс, который имеет финализатор. Это сообщает Сборщику "мусора" (GC), что this объект был очищен полностью.

рекомендуемый шаблон IDisposable, когда у Вас есть финализатор:

public class MyClass : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // called via myClass.Dispose(). 
                // OK to use any private object references
            }
            // Release unmanaged resources.
            // Set large fields to null.                
            disposed = true;
        }
    }

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
}

Обычно, CLR следит за объектами с финализатором, когда они создаются (создание их более дорогой для создания). SuppressFinalize говорит GC, что объект был очищен правильно и не должен идти на очередь финализатора. Это похоже на деструктор C++, но не действует ничто как одно.

оптимизация SuppressFinalize не тривиальна, поскольку Ваши объекты могут жить долгое время, ожидая на очереди финализатора. Не испытывайте желание звонить, SuppressFinalize на других объектах возражают против Вас. Это - серьезный неизбежный дефект.

Руководство по проектированию сообщает нам, что финализатор не необходим, если Ваш объект реализует IDisposable, но если у Вас есть финализатор, необходимо реализовать IDisposable для разрешения детерминированной очистки класса.

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

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

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
    #if DEBUG
        GC.SuppressFinalize(this);
    #endif
    }

    #if DEBUG
    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
    #endif
286
ответ дан Robert Paulson 23 November 2019 в 02:16
поделиться

Вы говорите системе, что независимо от того, что работа была бы сделана в финализаторе, был уже сделан, таким образом, финализатор не должны называть. Из документов.NET:

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

В целом, большинство любой Располагает (), метод должен быть в состоянии назвать GC.SupressFinalize (), потому что это должно очистить все, что было бы убрано в финализаторе.

SupressFinalize - просто что-то, что обеспечивает оптимизацию, которая позволяет системе не беспокоить организацию очередей объект к потоку финализатора. Правильно записанный Располагают ()/, финализатор должен работать правильно с или без вызова к GC.SupressFinalize ().

37
ответ дан Michael Burr 23 November 2019 в 02:16
поделиться

К тому методу нужно обратиться Расположить метод объектов, который реализует IDisposable, таким образом GC не назвал бы финализатор другим временем, если someones называет Расположить метод.

См.: http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx

2
ответ дан GEOCHET 23 November 2019 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: