代码之家  ›  专栏  ›  技术社区  ›  jethro

如何检查对象是否已在C#[副本]中释放

  •  61
  • jethro  · 技术社区  · 15 年前

    可能重复:
    How does one tell if an IDisposable object reference is disposed?

    是否有一种方法来检查对象是否被不同的方式处理

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

    我用的是 TcpClient 拥有 Close() 方法处理对象,这可能发生在我无法控制的代码段中。在这种情况下,我希望有更好的解决方案,然后捕捉异常。

    4 回复  |  直到 8 年前
        1
  •  39
  •   Plater    6 年前

    一个好方法是从TcpClient派生并重写Disposing(bool)方法:

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

    如果另一个代码创建了实例,这将不起作用。然后,您必须做一些绝望的事情,比如使用反射来获取私有m\u CleanedUp成员的值。或者捕捉异常。

    坦率地说,没有人认为这会有一个很好的结局。你真的 你的

    编辑:反射示例:

    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);
    }
    
        2
  •  46
  •   Luca    15 年前

    编写Dispose方法的重写实现的解决方案不起作用,因为在调用Dispose方法的线程和访问对象的线程之间存在竞争条件:在检查了假设的IsDisposed属性之后,可以真正地释放对象,同时抛出异常。

    this ),用于向每个感兴趣的对象通知处理对象,但根据软件设计,这可能很难计划。

        3
  •  17
  •   Ryan Brunner    15 年前

    如果不确定对象是否已被释放,则应调用 Dispose 方法本身,而不是 Close . 虽然框架不能保证Dispose方法必须毫无例外地运行,即使对象以前被释放过,但据我所知,这是一种常见的模式,在框架中的所有一次性对象上都实现了。

    典型的模式 处置 ,根据 Microsoft

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

    注意检查 _disposed 处置

    推荐文章