Pergunta

Existe um método, ou alguma outra forma leve, para verificar se a referência é a um objeto descartado?

P.S. - Esta é apenas uma curiosidade (sleep bem, não no código de produção). Sim, eu sei que posso pegar o ObjectDisposedException ao tentar acessar um membro do objeto.

Foi útil?

Solução

Depende, existem objetos IDisposable que permitem chamar o método Dispose tanto quanto você quer, e há IDisposable objetos que ObjectDisposedException lance. Em tal caso, um desses objetos devem controlar o estado (geralmente implementado com um isDisposed privado campo booleano).

Outras dicas

Não - implementação padrão do padrão IDisposable não apoiá-lo

System.Windows.Forms.Control tem um IsDisposed propriedade que é conjunto para true após Dispose() é chamado . Em seus próprios objetos IDisposable, você pode facilmente criar uma propriedade semelhante.

Não há nada construído em que irá permitir isso. Você precisaria para expor uma propriedade boolean IsDisposed que reflete uma bandeira dispostos interno.

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);
    }
}

Se não for sua classe e ele não fornece uma propriedade IsDisposed. (Ou algo similar - o nome é apenas uma convenção), então você tem nenhuma maneira de saber

Mas se é sua classe e você está seguindo o canônica implementação IDisposable , em seguida, basta expor o campo _disposed ou _isDisposed como uma propriedade e verifique se.

O método Dispose é necessária para realizar qualquer limpeza será necessária antes de um objeto é abandonado; Se nenhuma limpeza é necessária, não é necessário fazer nada. Exigindo um objeto para controlar se ele foi descartado, mesmo quando o método Dispose de outra forma, não fazer nada, exigiria muitos IDisposable objetos para adicionar um sinalizador para benefício muito limitado.

Pode ter sido útil se IDisposable incluiu duas propriedades - uma que indicou se um objeto necessário descartar , e um dos que indicou que o objeto não tinha sido inutilizados por disposição. Para objetos onde disposição realmente faz alguma coisa, ambos os valores seriam inicialmente verdade, e se tornaria falsa após Dispose. Para objetos onde disposição não precisa fazer qualquer limpeza, o primeiro método pode sempre retornar falso eo segundo sempre verdadeiro, sem ter que armazenar uma bandeira em qualquer lugar. Eu não acho que há alguma maneira aqueles podem ser adicionados ao .NET agora, no entanto.

Eu vejo isso é velho, mas eu não vi uma resposta. Alguns nem todos os objetos descartáveis ??como um DataSet tem um evento dispostos você pode anexar.

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;
    }
}

O que eu gostaria de fazer é declarar os objetos sem inicializar-los, mas definir os valores padrão para Nothing. Então, no final da gravação ciclo I:

If anObject IsNot Nothing Then anObject.Dispose()

Aqui está um exemplo completo:

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

Isso também funciona muito bem para colocar os seus principais objetos no topo de uma rotina, utilizando-os dentro de uma rotina Try, e depois descartá-los em um bloco Finally:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top