2010-05-07 4 views
3

Overriding the Finalize methodObject.Finalize documentation에 설명 된대로 답변이 "아니오"라는 것을 알고있었습니다. 때문에 정확한 방법에finalizer는 다른 관리되는 클래스의 메서드를 호출 할 수 있습니까?

private SafeFileHandle _handle; 

~FileStream() 
{ 
    if (this._handle != null) 
    { 
     this.Dispose(false); 
    } 
} 

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     ... 
    } 
    finally 
    { 
     if ((this._handle != null) && !this._handle.IsClosed) // <=== HERE 
     { 
      this._handle.Dispose(); // <=== AND HERE 
     } 
     [...] 
    } 
} 

내가이 항상 작동 여부 궁금 시작 : 무작위 반사경에 FileStream을 검색하는 동안

그러나, 나는 그것이 실제로 파이널에서 바로 그러한 메서드를 호출 할 수 있다는 것을 발견 그것은 작성된 것이고, 따라서 "finalizer에서 관리 클래스를 건드리지 마라"는 올바른 이유와 필요한 지식을 고려할 때 깨뜨릴 수있는 지침 일뿐입니다.

"규칙"이 깨졌을 때 발생할 수있는 최악의 상황은 액세스되는 관리 대상 개체가 이미 완료되었거나 별도의 스레드에서 병렬로 완료 될 수 있다는 것입니다. 그래서 SafeFileHandle의 finalizer가 Dispose에 대한 후속 호출이 실패 할 경우 아무것도하지 않으면 위의 내용이 정상적으로 처리되어야합니다 ... 맞습니까?

질문 : 결국 다른 관리 클래스의 메소드는 파이널에서 안정적으로를 호출 할 수있는 상황이있을 수 있습니다 그래서? 저는 항상 이것을 거짓이라고 믿었습니다. 그러나이 코드는 가능한 일이며 충분한 이유가있을 수 있음을 시사합니다.

보너스 :이 Dispose() 단지 일반 전화이기 때문에 SafeFileHandle도, 그것이 종료 자에서 호출되는 것을 알고하지 않습니다 관찰한다. 기본 클래스 인 SafeHandle에는 실제로 두 가지 전용 메서드 인 InternalDisposeInternalFinalize이 있으며이 경우 InternalDispose이 호출됩니다. 이게 문제가 아닌가? 왜 안 되니? ...

답변

2

그렇습니다. 파이널 라이저는 다른 방법을 호출 할 수 있습니다. 예를 들어, 종결을위한 유형을 다시 등록하는 것과 같은 재미있는 작업을 수행 할 수도 있습니다. 그러나 파이널 라이저가 임의의 순서로 실행되지 않을 수 있으므로 finalizable 인스턴스를 처리 할 때 null을 명시 적으로 확인해야합니다.

그럴 경우 가능한 한 많은 정보를 잘 닫아야합니다. 핸들이 아직 완성되지 않았다면 차갑게 처리하십시오. 그렇지 않으면 잘 마무리합니다.

관련 문제