Programing

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

lottogame 2020. 10. 6. 07:42
반응형

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


참조가 삭제 된 객체에 대한 것인지 확인하는 방법 또는 다른 가벼운 방법이 있습니까?

추신-이것은 단지 호기심입니다 (프로덕션 코드가 아니라 잘 자십시오). 예, ObjectDisposedException객체의 멤버에 액세스하려고 할 때를 잡을 수 있다는 것을 알고 있습니다 .


그것은이있다, 따라 IDisposable부르는 할 수 있도록 개체를 Dispose원하는만큼 방법, 그리고 거기에 IDisposable던져 객체 ObjectDisposedException. 이러한 경우 이러한 객체는 상태를 추적해야합니다 (일반적으로 개인 부울 필드로 구현 됨 isDisposed).


아니오-IDisposable 패턴의 기본 구현이이를 지원하지 않습니다.


System.Windows.Forms.ControlIsDisposed되는 재산 후 true로 설정 Dispose()호출됩니다 . 고유 한 IDisposable 개체에서 유사한 속성을 쉽게 만들 수 있습니다.


이것을 허용하는 내장 된 것은 없습니다. 내부 삭제 플래그를 반영하는 IsDisposed 부울 속성을 노출해야합니다.

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

    public bool IsDisposed
    {
       get
       {
          return disposed;
       }
    }

    public SimpleCleanup()
    {
        this.handle = /*...*/;
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
               // free only managed resources here
            }

            // free unmanaged resources here
            disposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
    }
}

그것이 당신의 클래스가 아니고 IsDisposed 속성 (또는 비슷한 것-이름은 단지 관례 일뿐)을 제공하지 않는다면, 당신은 알 수있는 방법이 없습니다.

그러나 그것이 당신의 클래스이고 표준 IDisposable 구현을 따르는 경우 _disposed 또는 _isDisposed 필드를 속성으로 노출하고 확인하십시오.


Dispose메서드는 개체를 버리기 전에 필요한 정리를 수행하는 데 필요합니다. 정리가 필요하지 않은 경우 아무것도 수행 할 필요가 없습니다. Dispose메서드가 아무 작업도하지 않더라도 객체가 폐기되었는지 여부를 추적하도록 요구하려면 IDisposable매우 제한된 이점을 위해 많은 객체가 플래그를 추가해야합니다.

IDisposable두 가지 속성을 포함 하면 도움이 될 수 있습니다. 하나는 객체를 폐기 해야하는지 여부를 표시 하고 하나는 객체가 폐기 인해 쓸모 없게 렌더링 되지 않았 음을 나타냅니다 . 처리가 실제로 어떤 작업을 수행하는 객체의 경우 두 값 모두 처음에는 true이고 Dispose. 처리 할 때 정리할 필요가없는 개체의 경우 첫 번째 메서드는 항상 false를 반환하고 두 번째 메서드는 플래그를 어디에도 저장할 필요없이 항상 true를 반환 할 수 있습니다. 하지만 지금은 .NET에 추가 할 수있는 방법이 없다고 생각합니다.


나는 이것이 오래된 것 같지만 대답을 보지 못했습니다. DataSet과 같은 일부 일회용 개체에는 연결할 수있는 삭제 된 이벤트가 있습니다.

class DisposeSample : IDisposable
{
    DataSet myDataSet = new DataSet();
    private bool _isDisposed;

    public DisposeSample()
    {
        // attach dispose event for myDataSet
        myDataSet.Disposed += MyDataSet_Disposed;
    }

    private void MyDataSet_Disposed(object sender, EventArgs e)
    {
        //Event triggers when myDataSet is disposed
        _isDisposed = true; // set private bool variable as true 
    }


    public void Dispose()
    {
        if (!_isDisposed) // only dispose if has not been disposed;
            myDataSet?.Dispose(); // only dispose if myDataSet is not null;
    }
}

What I like to do is declare the objects without initializing them, but set their default values to Nothing. Then, at the end of the loop I write:

If anObject IsNot Nothing Then anObject.Dispose()

Here is a complete sample:

Public Sub Example()
    Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing

    'code goes here that may or may not end up using all three objects, 
    ' such as when I see that there aren't enough pages in the pdf once I open  
    ' the pdfreader and then abort by jumping to my cleanup routine using a goto ..

GoodExit:
    If inputPdf IsNot Nothing Then inputPdf.Dispose()
    If inputDoc IsNot Nothing Then inputDoc.Dispose()
    If outputWriter IsNot Nothing Then outputWriter.Dispose()
End Sub

This also works great for putting your main objects at the top of a routine, using them inside a Try routine, and then disposing them in a Finally block:

Private Sub Test()
    Dim aForm As System.Windows.Forms.Form = Nothing
    Try
        Dim sName As String = aForm.Name  'null ref should occur
    Catch ex As Exception
        'got null exception, no doubt
    Finally
        'proper disposal occurs, error or no error, initialized or not..
        If aForm IsNot Nothing Then aForm.Dispose()
    End Try
End Sub

참고URL : https://stackoverflow.com/questions/192206/how-does-one-tell-if-an-idisposable-object-reference-is-disposed

반응형