developer tip

개체가 C #에서 삭제되었는지 확인하는 방법

optionbox 2020. 11. 12. 08:07
반응형

개체가 C #에서 삭제되었는지 확인하는 방법


중복 가능성 :
IDisposable 개체 참조가 삭제되었는지 어떻게 알 수 있습니까?

객체가 다른 방식으로 처리되었는지 확인하는 방법이 있습니까?

try
{
    myObj.CallRandomMethod();
} catch (ObjectDisposedException e)
{
    // now I know object has been disposed
}

제 경우에는 객체를 처리하는 메서드가있는 TcpClient클래스를 사용 Close()하고 있는데 이것은 제가 제어 할 수없는 코드에서 발생할 수 있습니다. 이 경우 예외를 잡은 다음 더 나은 솔루션을 원합니다.


좋은 방법은 TcpClient에서 파생하고 Disposing (bool) 메서드를 재정의하는 것입니다.

class MyClient : TcpClient {
    public bool IsDead { get; set; }
    protected override void Dispose(bool disposing) {
        IsDead = true;
        base.Dispose(disposing);
    }
}

다른 코드가 인스턴스를 만든 경우 작동하지 않습니다. 그런 다음 Reflection을 사용하여 개인 m_CleanedUp 멤버의 값을 가져 오는 것과 같은 필사적 인 작업을 수행해야합니다. 또는 예외를 포착하십시오.

솔직히 말해서 이것이 아주 좋은 결과를 낳을 것 같지는 않습니다. 당신은 정말 않았다 TCP 포트에 쓰기로합니다. 그러나 당신은 당신이 통제 할 수없는 버그 코드의 제어에 있는지,하지 않습니다 당신의 코드입니다. 버그의 영향을 증가 시켰습니다. 해당 코드의 소유자와 대화하고 작업하는 것이 가장 좋은 해결책입니다.

편집 : 반사 예 :

using System.Reflection;
public static bool SocketIsDisposed(Socket s)
{
   BindingFlags bfIsDisposed = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty;
   // Retrieve a FieldInfo instance corresponding to the field
   PropertyInfo field = s.GetType().GetProperty("CleanedUp", bfIsDisposed);
   // Retrieve the value of the field, and cast as necessary
   return (bool)field.GetValue(s, null);
}

안정적인 솔루션은 ObjectDisposedException을 포착하는 것입니다.

Dispose 메서드를 호출하는 스레드와 개체에 액세스하는 스레드간에 경쟁 조건이 있기 때문에 재정의 된 Dispose 메서드 구현을 작성하는 솔루션이 작동하지 않습니다. 가상 IsDisposed 속성을 확인한 후 개체가 실제로 삭제 될 수 있습니다. , 예외를 모두 똑같이 던집니다.

또 다른 접근 방식은 관심있는 모든 개체에 개체 처리에 대해 알리는 데 사용되는 가상 이벤트 Disposed (예 : 이와 같이)를 노출 할 수 있지만 소프트웨어 디자인에 따라 계획하기 어려울 수 있습니다.


객체가 삭제되었는지 여부가 확실하지 않은 Dispose경우 .NET Framework와 같은 메서드 대신 메서드 자체를 호출해야합니다 Close. 프레임 워크는 개체가 이전에 삭제 된 경우에도 Dispose 메서드가 예외없이 실행되어야한다고 보장하지는 않지만, 일반적인 패턴이며 프레임 워크의 모든 일회용 개체에 구현 된 것입니다.

의 일반적인 패턴 Dispose에 따라, 마이크로 소프트 :

public void Dispose() 
{
    Dispose(true);

    // Use SupressFinalize in case a subclass
    // of this type implements a finalizer.
    GC.SuppressFinalize(this);      
}

protected virtual void Dispose(bool disposing)
{
    // If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource.
    if (!_disposed)
    {
        if (disposing) {
            if (_resource != null)
                _resource.Dispose();
                Console.WriteLine("Object disposed.");
        }

        // Indicate that the instance has been disposed.
        _resource = null;
        _disposed = true;   
    }
}

Notice the check on _disposed. If you were to call a Dispose method implementing this pattern, you could call Dispose as many times as you wanted without hitting exceptions.


Best practice says to implement it by your own using local boolean field: http://www.niedermann.dk/2009/06/18/BestPracticeDisposePatternC.aspx

참고URL : https://stackoverflow.com/questions/3457521/how-to-check-if-object-has-been-disposed-in-c-sharp

반응형