마무리 대 처리


답변:


121

다른 사람들은 이미 ( Dispose와 언어 정의에서 소멸 Finalize자라고하는 Finalize방법 사이의) 차이점을 이미 다루었 으므로 Finalize메소드가 유용한 시나리오에 대해 조금만 추가 할 것입니다.

일부 유형은 일회용 자원을 사용하고 폐기하기 쉬운 방식으로 일회용 자원을 캡슐화합니다. 일반적인 사용법은 종종 다음과 같습니다 : 열기, 읽기 또는 쓰기, 닫기 (처리). using구조 와 매우 잘 어울립니다 .

다른 사람들은 조금 더 어렵다. WaitEventHandles예를 들어 하나의 스레드에서 다른 스레드로 신호를 보내는 데 사용되므로 이와 같이 사용되지 않습니다. 그러면 질문은 누가 Dispose이것을 불러야 합니까? 이와 같은 보호 유형으로, Finalize메소드가 구현 되어 인스턴스가 더 이상 애플리케이션에서 참조되지 않을 때 자원이 삭제되도록합니다.


60
이 승인 된 답변을 이해할 수 없습니다. 나는 아직도 다른 것을 알고 싶다. 무엇입니까?
Ismael

22
@Ismael : Finalize정당화 될 수있는 가장 큰 상황 은 자원을 유지하는 데 관심이있는 많은 객체가있을 때이지만 자원에 관심이없는 객체가 그것이 있는지 여부를 알 수있는 방법은 없습니다 마지막 하나. 이 경우, Finalize아무도 오브젝트에 관심이 없을 때만 발생합니다. 느슨해 진 타이밍은 Finalize파일 및 잠금과 같은 대체 불가능한 리소스에는 끔찍하지만, 대체 가능한 리소스에는 적합 할 수 있습니다.
supercat

13
+1하여 새롭고 멋진 단어를 전합니다. 상황은 꽤 분명해졌지만 우리 중 일부를 위해 wikipedia는 다음과 같이 말합니다. "우연 함은 개별 원단위 (예 : 단 원유와 같은 상호 대체 할 수있는 상품 또는 상품) 회사, 채권, 귀금속 또는 통화 "
Jon Coombs

5
@JonCoombs : "가용 한 자원"이라는 용어는 그들이 풀릴 때까지 자유롭게 대체 가능한 것들에 적용 되고 릴리스 또는 포기 후에 다시 자유롭게 대체 될 수 있다는 것에 주목할 가치 가 있습니다 . 시스템에 잠금 오브젝트 풀이 있고 코드가 일부 엔티티와 연관되는 오브젝트를 확보 한 경우, 해당 엔티티와 연관시키기 위해 해당 잠금에 대한 참조를 보유하고있는 한 , 해당 잠금은 다음으로 대체되지 않을 수 있습니다. 다른 것. 그러나 보호 대상 개체를 관리하는 모든 코드가 잠금을 포기하면 ...
supercat

... 그런 다음 다른 개체와 관련 될 때까지 다시 자유롭게 대체 할 수있게되었습니다.
supercat

135

finalizer 메소드는 객체가 가비지 수집 될 때 호출되며 이러한 상황이 언제 발생하는지 보장 할 수 없습니다 (강제화 할 수는 있지만 성능이 저하 될 수 있습니다).

Dispose반면에 방법은 당신이 청소하고 귀하가 취득한 모든 자원 (관리되지 않는 데이터, 데이터베이스 연결, 파일 핸들 등) 코드가 이루어집니다 순간을 해제 할 수 있도록 클래스를 생성 한 코드에 의해 호출하기위한 것입니다 당신의 물건.

표준 방법은 구현하는 것입니다 IDisposable그리고 Dispose당신은 당신의 객체를 사용할 수 있도록 using한 Statment. 와 같은 using(var foo = new MyObject()) { }. 그리고 종료 Dispose코드에서는 호출 코드가 처리하지 못한 경우를 대비하여 호출합니다.


17
Finalize 구현에서 Dispose를 호출하는 데 약간의주의가 필요합니다. Dispose는 관리 대상 리소스도 처분 할 수 있습니다. 이미 관리 대상 리소스가 이미 확정 되었기 때문에 마무리 프로그램에서 처리하고 싶지 않습니다.
itowlson 2009

6
@itowlson : 객체를 두 번 폐기 할 수 있다는 가정과 함께 null을 확인하면 (두 번째 호출은 아무것도하지 않음) 충분해야합니다.
사무엘

7
선택적인 관리되는 구성 요소 처리를 처리하기위한 표준 IDisposal 패턴과 Dispose (bool)의 숨겨진 구현은 해당 문제를 해결하는 것으로 보입니다.
Brody

소멸자 (~ MyClass () 메소드)를 구현할 이유가 없으며 Dispose () 메소드를 항상 구현하고 호출해야합니다. 아니면 내가 틀렸어? 둘 다 구현해야 할 때 누군가가 예를 들어 줄 수 있습니까?
dpelisek

66

Finalize는 가비지 수집기가 개체를 회수 할 때 호출되는 백스톱 방법입니다. Dispose는 GC가 개체에 반올림 될 때까지 무기한으로 유지하지 않고 더 이상 필요하지 않을 때 유용한 네이티브 리소스 (창 핸들, 데이터베이스 연결 등)를 해제하기 위해 응용 프로그램에서 호출하는 "결정적 정리"방법입니다.

개체의 사용자는 항상 Dispose를 사용합니다. 마무리는 GC를위한 것입니다.

클래스의 구현 자로서 폐기해야하는 관리 자원을 보유하면 Dispose를 구현합니다. 네이티브 리소스를 보유하고 있으면 Dispose와 Finalize를 모두 구현하고 네이티브 리소스를 해제하는 일반적인 메서드를 호출합니다. 이러한 관용구는 일반적으로 호출을 true로 처리하고 호출을 false로 마무리하는 개인 Dispose (bool disposing) 방법을 통해 결합됩니다. 이 메소드는 항상 기본 자원을 해제 한 다음 처리 매개 변수를 확인하고, 참이면 관리 자원을 처리하고 GC.SuppressFinalize를 호출합니다.



2
자체 청소 ( "관리") 자원과 비 자체 청소 ( "관리되지 않는") 자원이 혼합 된 클래스에 권장되는 원래 패턴은 오랫동안 사용되지 않습니다. 더 나은 패턴은 관리되지 않는 모든 리소스를 정리할 필요가없는 항목에 대한 강력한 참조를 보유하지 않는 자체 관리 객체로 개별적으로 래핑하는 것입니다. 최종화 가능한 객체가 직접 또는 간접적으로 강력한 참조를 보유하는 모든 것의 GC 수명이 연장됩니다. 정리에 필요한 것들을 캡슐화하면 그렇지 않은 것들의 GC 수명 연장을 피할 수 있습니다.
supercat

2
@JCoombs : Dispose좋고, 올바르게 구현하는 것은 일반적으로 쉽다. Finalize악의적이며 올바르게 구현하는 것은 일반적으로 어렵습니다. 무엇보다도 GC는 객체에 대한 참조가 존재하는 한 객체의 아이덴티티가 "재활용"되지 않도록 보장하기 때문에 Disposable일부 객체는 이미 정리되어있을 수 있습니다. 문제 없어요; Dispose이미 호출 된 객체에 대한 참조 는 이미 호출 된 객체에 대한 참조로 유지됩니다 Dispose.
supercat

2
@JCoombs : 관리되지 않는 리소스는 이와 대조적으로 일반적으로 보장되지 않습니다. object가 Fred파일 핸들 # 42를 소유하고 닫으면 시스템은 다른 엔티티에 부여 된 파일 핸들에 동일한 번호를 첨부 할 수 있습니다. 이 경우 파일 핸들 # 42는 Fred의 닫힌 파일이 아니라 해당 다른 엔티티에서 사용중인 파일을 나타냅니다. 위해 Fred가까운 핸들 # 42하려고 다시 재앙이 될 것입니다. 관리되지 않는 개체 하나가 아직 릴리스되었는지 여부를 100 % 안정적으로 추적하는 것이 가능합니다. 여러 객체를 추적하는 것은 훨씬 어렵습니다.
supercat

2
@JCoombs : 모든 관리되지 않는 자원은 수명, 자원이 해제되었는지 여부를 알 수 없습니다 후 외부 코드를 제어 아무것도하지 않습니다하지만 자신의 래퍼 객체에 배치하지만해야한다고 알고있는 경우 가 아직되어 있지 않은 경우 , 래퍼 객체가 안전하게 해제하도록 요청할 수 있습니다. 랩퍼 오브젝트는이를 수행했는지 여부를 알고 요청을 수행하거나 무시할 수 있습니다. GC가 래퍼에 대한 참조가 항상 래퍼에 대한 유효한 참조임을 보증한다는 사실은 매우 유용한 보증입니다.
supercat

43

마무리

  • 종료 자 항상해야 protected하지, public또는 private메소드가 직접 응용 프로그램의 코드에서 호출 할 수 없습니다 수 있도록 함과 동시에, 그것은를 호출 할 수 base.Finalize방법을
  • 종료자는 관리되지 않는 리소스 만 해제해야합니다.
  • 프레임 워크는 종료자가 주어진 인스턴스에서 전혀 실행되지 않을 것이라고 보장하지 않습니다.
  • 종료 자에 메모리를 할당하거나 종료 자에서 가상 메소드를 호출하지 마십시오.
  • 파이널 라이저에서 동기화 및 처리되지 않은 예외를 발생시키지 마십시오.
  • 종료 자의 실행 순서는 결정적이지 않습니다. 즉, 종료 자 내에서 여전히 사용 가능한 다른 개체에 의존 할 수 없습니다.
  • 값 유형에 종료자를 정의하지 마십시오.
  • 빈 소멸자를 만들지 마십시오. 다시 말해, 클래스가 관리되지 않는 리소스를 정리해야하는 경우가 아니면 명시 적으로 소멸자를 정의해서는 안되며 정의한 경우 일부 작업을 수행해야합니다. 나중에 소멸자에서 관리되지 않는 리소스를 더 이상 정리할 필요가 없으면 제거하십시오.

처분

  • 종료 IDisposable자가있는 모든 유형에 구현
  • Dispose메소드를 호출 한 후 오브젝트를 사용할 수 없는지 확인하십시오 . 즉, Dispose메소드가 호출 된 후 오브젝트를 사용하지 마십시오 .
  • Dispose모든 IDisposable유형을 완료하면 전화하십시오 .
  • 허용 Dispose오차를 발생시키지 않고 여러 번 호출 할 수 있습니다.
  • Dispose메소드를 사용하여 GC.SuppressFinalize메소드 내에서 최종 호출을 나중에 억제
  • 일회용 값 유형을 생성하지 마십시오
  • Dispose메소드 내에서 예외를 던지지 마십시오

폐기 / 최종 패턴

  • Microsoft는 모두 구현하는 것을 권장 Dispose하고 Finalize관리되지 않는 리소스로 작업 할 때. Finalize구현이 실행됩니다 및 자원이 여전히 객체는 개발자가 전화를 무시하면 쓰레기도 수집 될 때 발표 될 것이다 Dispose명시 적 방법을.
  • Finalize방법과 방법 에서 관리되지 않는 리소스를 정리하십시오 Dispose. 또한 Dispose메서드에서 관리되지 않는 리소스를 멤버로 사용하여 해당 클래스 내부의 구성 요소로 사용하는 모든 .NET 개체에 대해 메서드를 호출하십시오 Dispose.

17
나는 어디에서 나이 동일한 대답을 읽었지만 여전히 각각의 목적이 무엇인지 이해할 수 없습니다. 나는 규칙 후에 만 ​​규칙을 읽습니다.
Ismael

@Ismael : 또한 저자는 MSDN에서 일부 텍스트를 복사하여 붙여 넣는 것 외에는 아무것도 추가하지 않습니다.
Tarik

@tarik 나는 이미 그것을 배웠다. 나는 내가 이것을 물었을 때 "약속"개념을 가지고 있었다.
Ismael

31

이 개체를 더 이상 사용하지 않으면 GC에서 Finalize를 호출합니다.

Dispose는이 클래스의 사용자가 모든 리소스를 해제하기 위해 호출 할 수있는 일반적인 방법입니다.

사용자가 Dispose 호출을 잊어 버렸고 클래스에 Finalize가 구현되어 있으면 GC가 호출되는지 확인합니다.


3
지금까지 깨끗한 대답
dariogriffo

19

MCSD Certification Toolkit (시험 70-483) 문서 193에는 몇 가지 열쇠가 있습니다.

소멸자 ≈ (거의 같음)base.Finalize() , 소멸자는 소멸자의 코드를 실행 한 다음 기본 클래스의 Finalize 메소드를 호출하는 Finalize 메소드의 대체 버전으로 변환됩니다. 그렇다면 GC에 의존하기 때문에 언제 호출 될지 알 수없는 완전히 비 결정적입니다.

클래스에 관리 자원이없고 관리되지 않는 자원이 없으면 클래스를 구현 IDisposable하거나 소멸자가 없어야합니다 .

클래스에 managed resources 만있는 경우 구현해야 IDisposable하지만 소멸자가 없어야합니다. 소멸자가 실행될 때 관리 객체가 여전히 존재하는지 확인할 수 없으므로 해당 Dispose()메소드를 호출 할 수 없습니다 .

클래스에 관리되지 않는 리소스 만IDisposable 있는 경우 프로그램이 호출하지 않는 경우 소멸자 를 구현 해야합니다 Dispose().

Dispose()메소드는 두 번 이상 실행하기에 안전해야합니다. 변수를 사용하여 이전에 실행되었는지 여부를 추적하여이를 달성 할 수 있습니다.

Dispose()관리되는 리소스와 관리되지 않는 리소스를 모두 해제해야합니다 .

소멸자는 관리되지 않는 리소스 만 해제해야합니다 . 소멸자가 실행될 때 관리 대상 개체가 여전히 존재하는지 확인할 수 없으므로 Dispose 메서드를 호출 할 수 없습니다. 이는 표준 protected void Dispose(bool disposing)관리 패턴 을 사용하여 얻을 수 있으며 여기서 관리 자원 만 해제 (처리)됩니다 disposing == true.

리소스를 해제 한 후을 Dispose()호출해야GC.SuppressFinalize 개체가 종료 큐를 건너 뛸 수 있습니다.

관리되지 않고 관리되는 리소스가있는 클래스에 대한 구현 예 :

using System;

class DisposableClass : IDisposable
{
    // A name to keep track of the object.
    public string Name = "";

    // Free managed and unmanaged resources.
    public void Dispose()
    {
        FreeResources(true);

        // We don't need the destructor because
        // our resources are already freed.
        GC.SuppressFinalize(this);
    }

    // Destructor to clean up unmanaged resources
    // but not managed resources.
    ~DisposableClass()
    {
        FreeResources(false);
    }

    // Keep track if whether resources are already freed.
    private bool ResourcesAreFreed = false;

    // Free resources.
    private void FreeResources(bool freeManagedResources)
    {
        Console.WriteLine(Name + ": FreeResources");
        if (!ResourcesAreFreed)
        {
            // Dispose of managed resources if appropriate.
            if (freeManagedResources)
            {
                // Dispose of managed resources here.
                Console.WriteLine(Name + ": Dispose of managed resources");
            }

            // Dispose of unmanaged resources here.
            Console.WriteLine(Name + ": Dispose of unmanaged resources");

            // Remember that we have disposed of resources.
            ResourcesAreFreed = true;
        }
    }
}

2
이것은 좋은 대답입니다! 그러나 나는 이것이 틀렸다고 생각한다 : "소멸자는 GC.SuppressFinalize를 불러야한다". 대신, 공개 Dispose () 메소드가 GC.SuppressFinalize를 호출해서는 안됩니까? 참조 : docs.microsoft.com/en-us/dotnet/api/... 이 메서드를 호출하면 Object.Finalize을 (소멸자에 의해 무시되는) 호출에서 가비지 컬렉터를 방지 할 수 있습니다.
Ewa

7

시간의 99 %는 걱정할 필요가 없습니다. :) 그러나 개체에 관리되지 않는 리소스 (예 : 창 핸들, 파일 핸들)에 대한 참조가 있으면 관리되는 개체가 해당 리소스를 해제 할 수있는 방법을 제공해야합니다. Finalize는 리소스 해제를 암시 적으로 제어합니다. 가비지 수집기에서 호출합니다. Dispose는 리소스 릴리스를 명시 적으로 제어 할 수있는 방법이며 직접 호출 할 수 있습니다.

가비지 콜렉션 의 주제에 대해 훨씬 더 배울 것이 있지만 그것은 시작입니다.


5
C # 응용 프로그램의 1 % 이상이 데이터베이스를 사용 한다고 확신합니다. 여기서 IDisposable SQL에 대해 걱정 해야 합니다.
사무엘

1
또한 IDisposables를 캡슐화하는 경우 IDisposable을 구현해야합니다. 아마 다른 1 %를 차지할 것입니다.
Darren Clark

@Samuel : 데이터베이스와 어떤 관련이 있는지 모르겠습니다. 연결을 끊는 것에 대해 이야기하고 있다면 괜찮지 만 다른 문제입니다. 적시에 연결을 닫기 위해 객체를 배치 할 필요는 없습니다.
JP Alioto

1
@ JP : 그러나 Using (...) 패턴은 대처하기가 훨씬 간단합니다.
Brody

2
동의하지만 그것이 바로 요점입니다. using 패턴은 Dispose 호출을 숨 깁니다.
JP Alioto

6

종료자는 암시 적 정리를위한 것입니다. 클래스 / 클래스가 리소스를 관리 할 때마다 처리 해야합니다 . 그렇지 않으면 핸들 / 메모리 등이 누출 될 것입니다.

종료자를 올바르게 구현하는 것은 매우 어렵고 가능한 경우 피해야합니다. SafeHandle클래스 (.Net v2.0 이상에서 사용 가능)는 이제 더 이상 종료자를 구현할 필요가 거의 없음을 의미합니다.

IDisposable인터페이스는 명시 적 정리를위한 것이며 훨씬 일반적으로 사용됩니다. 사용자가 객체 사용을 마칠 때마다 명시 적으로 리소스를 해제하거나 정리할 수 있도록하려면이 인터페이스를 사용해야합니다.

종료자가 IDisposable있는 경우 개체를 가비지 수집 한 경우보다 더 빨리 해당 리소스를 명시 적으로 해제 할 수 있도록 인터페이스를 구현해야합니다 .

파이널 라이저 및에 대한 최상의 권장 사항으로 간주되는 내용은 DG 업데이트 : 폐기, 마무리 및 리소스 관리 를 참조하십시오 IDisposable.


3

요약은-

  • 관리되지 않는 리소스에 대한 참조가 있고 해당 클래스의 인스턴스가 자동으로 가비지 수집 될 때 해당 관리되지 않는 리소스가 해제되도록하려면 종료자를 작성하십시오 . 객체의 Finalizer를 명시 적으로 호출 할 수는 없습니다. 가비지 수집기에서 필요에 따라 자동으로 호출합니다.
  • 반면에 클래스에 관리되지 않는 리소스에 대한 참조가 있지만 가비지 수집기가 시작되기를 원하지 않는 경우 IDisposable 인터페이스를 구현하고 결과적으로 클래스의 결과로 Dispose () 메서드를 정의합니다) (언제든지 프로그래머가 제어 할 수 없음), 완료하자마자 해당 리소스를 해제하려고합니다. 따라서 개체의 Dispose () 메서드를 호출하여 관리되지 않는 리소스를 명시 적으로 해제 할 수 있습니다 .

또한 Dispose () 구현에서 또 다른 차이점은 관리되는 리소스도 해제 해야하지만 Finalizer에서는 수행하지 않아야합니다. 오브젝트가 참조하는 관리 자원이 완료되기 전에 이미 정리되었을 가능성이 높기 때문입니다.

관리되지 않는 리소스를 사용하는 클래스의 경우 모범 사례는 Dispose () 메서드와 Finalizer를 모두 정의하여 개발자가 개체를 명시 적으로 폐기하는 것을 잊어 버린 경우 대비책으로 사용하는 것입니다. 둘 다 공유 방법을 사용하여 관리되는 리소스와 관리되지 않는 리소스를 정리할 수 있습니다.

class ClassWithDisposeAndFinalize : IDisposable
{
    // Used to determine if Dispose() has already been called, so that the finalizer
    // knows if it needs to clean up unmanaged resources.
     private bool disposed = false;

     public void Dispose()
     {
       // Call our shared helper method.
       // Specifying "true" signifies that the object user triggered the cleanup.
          CleanUp(true);

       // Now suppress finalization to make sure that the Finalize method 
       // doesn't attempt to clean up unmanaged resources.
          GC.SuppressFinalize(this);
     }
     private void CleanUp(bool disposing)
     {
        // Be sure we have not already been disposed!
        if (!this.disposed)
        {
             // If disposing equals true i.e. if disposed explicitly, dispose all 
             // managed resources.
            if (disposing)
            {
             // Dispose managed resources.
            }
             // Clean up unmanaged resources here.
        }
        disposed = true;
      }

      // the below is called the destructor or Finalizer
     ~ClassWithDisposeAndFinalize()
     {
        // Call our shared helper method.
        // Specifying "false" signifies that the GC triggered the cleanup.
        CleanUp(false);
     }

2

내가 아는 가장 좋은 예.

 public abstract class DisposableType: IDisposable
  {
    bool disposed = false;

    ~DisposableType()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(false);
      }
    }

    public void Dispose()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
      }
    }

    public void Close()
    {
      Dispose();
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing) 
      {
        // managed objects
      }
      // unmanaged objects and resources
    }
  }

2

C #에서 Finalize와 Dispose 메서드의 차이점

GC는 finalize 메소드를 호출하여 관리되지 않는 리소스 (예 : 파일 작업, Windows API, 네트워크 연결, 데이터베이스 연결)를 회수하지만 GC가 호출 할 때 시간이 고정되지 않습니다. GC에 의해 암시 적으로 호출됩니다. 이는 낮은 수준의 제어 권한이 없음을 의미합니다.

Dispose Method : 코드에서 호출 할 때 제어 수준이 낮습니다. 사용할 수 없다고 생각 될 때마다 관리되지 않는 리소스를 회수 할 수 있습니다. IDisposal 패턴을 구현하여이를 달성 할 수 있습니다.


1

클래스 인스턴스는 종종 창 핸들 (HWND), 데이터베이스 연결 등과 같이 런타임에 의해 관리되지 않는 리소스에 대한 제어를 캡슐화합니다. 따라서 이러한 자원을 해제 할 수있는 명시 적 및 암시 적 방법을 모두 제공해야합니다. 개체 (C #의 소멸자 구문 및 C ++의 Managed Extensions)에서 보호 된 Finalize 메서드를 구현하여 암시적인 제어 기능을 제공합니다. 가비지 수집기는 개체에 대한 유효한 참조가 더 이상 존재하지 않는 시점에서이 메서드를 호출합니다. 경우에 따라 가비지 수집기가 개체를 해제하기 전에 개체를 사용하여 프로그래머에게 이러한 외부 리소스를 명시 적으로 해제 할 수있는 기능을 제공 할 수 있습니다. 외부 리소스가 부족하거나 비싸면 더 이상 사용하지 않을 때 프로그래머가 명시 적으로 리소스를 해제하면 성능이 향상 될 수 있습니다. 명시적인 제어를 제공하려면 IDisposable 인터페이스에서 제공하는 Dispose 메서드를 구현하십시오. 객체의 소비자는 객체를 사용하여 완료되면이 메소드를 호출해야합니다. 객체에 대한 다른 참조가 살아 있어도 Dispose를 호출 할 수 있습니다.

Dispose를 통해 명시 적으로 제어 할 수있는 경우에도 Finalize 메서드를 사용하여 암시 적 정리를 제공해야합니다. Finalize는 프로그래머가 Dispose를 호출하지 않은 경우 리소스가 영구적으로 누출되지 않도록 백업을 제공합니다.


1

Dispose와 Finalize의 주요 차이점은 다음과 같습니다.

Dispose일반적으로 코드에서 호출합니다. 리소스를 호출하면 즉시 해제됩니다. 사람들은 메소드를 호출하는 것을 잊어 버리므로 using() {}진술이 발명됩니다. 프로그램이에서 코드 실행을 마치면 메소드가 자동으로 {}호출 Dispose됩니다.

Finalize코드에서 호출하지 않습니다. 가비지 콜렉터 (GC)가 호출해야합니다. 즉, GC가 결정할 때마다 언제든지 리소스가 해제 될 수 있습니다. GC가 작업을 수행하면 많은 Finalize 메서드를 거치게됩니다. 이것에 논리가 많으면 프로세스 속도가 느려집니다. 프로그램 성능 문제가 발생할 수 있습니다. 당신이 거기에 넣는 것에주의하십시오.

나는 개인적으로 Dispose에서 대부분의 파괴 논리를 쓸 것입니다. 바라건대, 이것은 혼란을 해결합니다.


-1

우리가 알다시피 dispose와 finalize는 관리되지 않는 리소스를 해제하는 데 사용됩니다. 그러나 차이점은 finalize는 두주기를 사용하여 리소스를 해제하는 반면, dispose는 하나의주기를 사용합니다.


Dispose는 리소스를 즉시 해제합니다 . Finalize는 어느 정도의 적시성으로 리소스를 해제하거나 해제하지 않을 수 있습니다.
supercat

1
: 아, 그 가능성이 더 여기 읽기 "는 종료 가능한 객체가 메모리를 회수하기 전에 두 번 GC 감지 할 필요가있다"의미 ericlippert.com/2015/05/18/...
aeroson

-4

첫 번째 부분에 대답하려면 사람들이 동일한 클래스 객체에 대해 다른 접근 방식을 사용하는 예제를 제공해야합니다. 그렇지 않으면 대답하기가 어렵거나 심지어 이상합니다.

두 번째 질문에 대해서는 먼저 IDisposable 인터페이스올바르게 사용하는 것이 좋습니다.

당신의 선택입니다! 그러나 폐기를 선택하십시오.

즉, GC는 종료 자 (있는 경우. Microsoft의 소멸자라고도 함)에 대해서만 알고 있습니다. 좋은 코드는 마무리 및 처리에서 정리를 시도합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.