2015-11-01 2 views
1

Почему мы используем Dispose(false)?Finalize/Dispose pattern in dotnet

Ниже код в шаблоне Dispose?

~MyClass() 
{ 
     Dispose(false); 
} 

Что произойдет, если я использую вместо этого Dispose(true)? Что произойдет Если я пропущу этот финализатор?

+0

Возможный дубликат [Финализировать/Убирать шаблон в C#] (http://stackoverflow.com/questions/898828/finalize-dispose-pattern-in-c-sharp) – Console

ответ

2

Идея переопределения метода Finalize с использованием Destructurs (~) заключается в том, чтобы получить возможность распоряжаться кодом управления или нет. В вашем примере вы передаете значение false, для которого используется управляемый ресурс. В следующем примере вы можете ясно видеть это. Примечание: Посмотрите, как я несколько раз вызываю метод Dispose, используя частный элемент «disposed».

public class Dog : IDisposable 
{ 
    // Prevent dispose from happening more than once 
    private bool disposed = false; 

    // IDisposable.Dispose 
    public void Dispose() 
    { 
     // Explicitly dispose of resources 
     DoDispose(true); 

     // Tell GC not to finalize us--we've already done it manually 
     GC.SuppressFinalize(this); 
    } 

    // Function called via Dispose method or via Finalizer 
    protected virtual void DoDispose(bool explicitDispose) 
    { 
     if (!disposed) 
     { 
      // Free some resources only when invoking via Dispose 
      if (explicitDispose) 
       FreeManagedResources(); // Define this method 

      // Free unmanaged resources here--whether via Dispose 
      // or via finalizer 
      FreeUnmanagedResources(); 

      disposed = true; 
     } 
    } 

    // Finalizer 
    ~Dog() 
    { 
     DoDispose(false); 
    } 
} 
1

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

Классы в .NET могут попросить систему наблюдать за экземплярами и сообщить им, если они, похоже, были оставлены. Это делается путем переопределения метода, называемого Finalize, который является частью типа Object. Если этот метод переопределен и не был подавлен, и система замечает, что объект будет иметь право на сбор, если не будет присутствовать активный финализатор, система переведет систему в очередь объектов, метод Finalize должен работать как можно скорее как практические и подавлять дальнейшие наблюдения за объектом (поэтому объект получит один снимок при запуске своего метода Finalize, но после этого он будет иметь право на сбор).

По какой-то причине я не понимаю, создатели C# решили запретить программистам, использующим этот язык, переопределить метод Finalize напрямую. Вместо этого требуется, чтобы они использовали специальный синтаксис, который, в свою очередь, инструктировал компилятор переопределить Finalize. Блок кода, отмеченный ~ClassName, будет выполняться, когда система замечает, что объект был оставлен, и запускает свой метод Finalize.