如何判断一个i可支配对象引用是否被处理?

时间:2021-09-06 16:59:14

Is there a method, or some other light-weight way, to check if a reference is to a disposed object?

是否有一种方法或其他轻量级的方法来检查引用是否指向一个已处理的对象?

P.S. - This is just a curiousity (sleep well, not in production code). Yes, I know I can catch the ObjectDisposedException upon trying to access a member of the object.

注:这只是一个有趣的问题(睡个好觉,而不是在生产代码中)。是的,我知道我可以在尝试访问对象的成员时捕获objectsedexception。

7 个解决方案

#1


-17  

It depends, there are IDisposable objects that allow to call the Dispose method as much as you want, and there are IDisposable objects that throw ObjectDisposedException. In such a case these objects must track the state (usually implemented with a private boolean field isDisposed).

它取决于,有IDisposable对象可以根据需要调用Dispose方法,也有抛出ObjectDisposedException的IDisposable对象。在这种情况下,这些对象必须跟踪状态(通常使用私有布尔字段来实现)。

#2


41  

No - default implementation of IDisposable pattern does not support it

IDisposable pattern的无默认实现不支持它

#3


36  

System.Windows.Forms.Control has an IsDisposed property which is set to true after Dispose() is called. In your own IDisposable objects, you can easily create a similar property.

System.Windows.Forms。控件有一个isdispose属性,该属性在调用Dispose()之后设置为true。在您自己的IDisposable对象中,您可以轻松创建类似的属性。

#4


16  

There is nothing built in that will allow this. You would need to expose an IsDisposed boolean property that reflects an internal disposed flag.

没有任何内在的东西会允许这一切。您需要公开一个isdispose布尔属性,该属性反映一个内部处理标志。

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

#5


9  

If it is not your class and it doesn't provide an IsDisposed property (or something similar - the name is just a convention), then you have no way of knowing.

如果它不是您的类,并且不提供isdispose属性(或类似的东西——名称只是一个约定),那么您无法知道。

But if it is your class and you are following the canonical IDisposable implementation, then just expose the _disposed or _isDisposed field as a property and check that.

但是,如果它是您的类,并且您正在遵循规范的IDisposable实现,那么只需将_dispose或_isdispose字段公开为属性,然后进行检查。

#6


2  

The Dispose method is required to perform whatever cleanup will be required before an object is abandoned; if no cleanup is required, it is not required to do anything. Requiring an object to keep track of whether it has been disposed, even when the Dispose method would otherwise do nothing, would require many IDisposable objects to add a flag for very limited benefit.

在放弃一个对象之前,需要使用Dispose方法执行任何清理工作;如果不需要清理,则不需要做任何事情。需要一个对象跟踪它是否已被处理,即使在处理方法不做任何事情的情况下,也需要许多IDisposable对象来添加标志,效果非常有限。

It might have been helpful if IDisposable included two properties--one which indicated whether an object needed disposing, and one of which indicated that the object had not been rendered useless by disposal. For objects where disposal actually does something, both values would be initially true, and would become false after Dispose. For objects where disposal doesn't need to do any cleanup, the first method could always return false and the second one always true, without having to store a flag anywhere. I don't think there's any way those can be added to .NET now, though.

如果一次性使用包括两个属性——一个表示一个对象是否需要处理,另一个表示该对象没有被处理无用,这可能是有用的。对于处理实际执行某些操作的对象,这两个值最初都为true,在处理后变为false。对于不需要进行任何清理的对象,第一个方法总是返回false,第二个方法总是true,而不需要在任何地方存储标志。不过,我认为现在没有任何方法可以添加到。net中。

#7


-1  

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:

我喜欢做的是声明对象而不初始化它们,但是将它们的默认值设置为none。然后,在循环的最后我写道:

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:

这也适用于将你的主要对象放在一个例程的顶部,在一个Try例程中使用它们,然后在一个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

#1


-17  

It depends, there are IDisposable objects that allow to call the Dispose method as much as you want, and there are IDisposable objects that throw ObjectDisposedException. In such a case these objects must track the state (usually implemented with a private boolean field isDisposed).

它取决于,有IDisposable对象可以根据需要调用Dispose方法,也有抛出ObjectDisposedException的IDisposable对象。在这种情况下,这些对象必须跟踪状态(通常使用私有布尔字段来实现)。

#2


41  

No - default implementation of IDisposable pattern does not support it

IDisposable pattern的无默认实现不支持它

#3


36  

System.Windows.Forms.Control has an IsDisposed property which is set to true after Dispose() is called. In your own IDisposable objects, you can easily create a similar property.

System.Windows.Forms。控件有一个isdispose属性,该属性在调用Dispose()之后设置为true。在您自己的IDisposable对象中,您可以轻松创建类似的属性。

#4


16  

There is nothing built in that will allow this. You would need to expose an IsDisposed boolean property that reflects an internal disposed flag.

没有任何内在的东西会允许这一切。您需要公开一个isdispose布尔属性,该属性反映一个内部处理标志。

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

#5


9  

If it is not your class and it doesn't provide an IsDisposed property (or something similar - the name is just a convention), then you have no way of knowing.

如果它不是您的类,并且不提供isdispose属性(或类似的东西——名称只是一个约定),那么您无法知道。

But if it is your class and you are following the canonical IDisposable implementation, then just expose the _disposed or _isDisposed field as a property and check that.

但是,如果它是您的类,并且您正在遵循规范的IDisposable实现,那么只需将_dispose或_isdispose字段公开为属性,然后进行检查。

#6


2  

The Dispose method is required to perform whatever cleanup will be required before an object is abandoned; if no cleanup is required, it is not required to do anything. Requiring an object to keep track of whether it has been disposed, even when the Dispose method would otherwise do nothing, would require many IDisposable objects to add a flag for very limited benefit.

在放弃一个对象之前,需要使用Dispose方法执行任何清理工作;如果不需要清理,则不需要做任何事情。需要一个对象跟踪它是否已被处理,即使在处理方法不做任何事情的情况下,也需要许多IDisposable对象来添加标志,效果非常有限。

It might have been helpful if IDisposable included two properties--one which indicated whether an object needed disposing, and one of which indicated that the object had not been rendered useless by disposal. For objects where disposal actually does something, both values would be initially true, and would become false after Dispose. For objects where disposal doesn't need to do any cleanup, the first method could always return false and the second one always true, without having to store a flag anywhere. I don't think there's any way those can be added to .NET now, though.

如果一次性使用包括两个属性——一个表示一个对象是否需要处理,另一个表示该对象没有被处理无用,这可能是有用的。对于处理实际执行某些操作的对象,这两个值最初都为true,在处理后变为false。对于不需要进行任何清理的对象,第一个方法总是返回false,第二个方法总是true,而不需要在任何地方存储标志。不过,我认为现在没有任何方法可以添加到。net中。

#7


-1  

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:

我喜欢做的是声明对象而不初始化它们,但是将它们的默认值设置为none。然后,在循环的最后我写道:

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:

这也适用于将你的主要对象放在一个例程的顶部,在一个Try例程中使用它们,然后在一个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