locked
SafeHandle.Dispose behavior RRS feed

  • Question

  • Consider the following code:

    SafeHandleDerivedClass safeHandle = OpenHandleDerivedClass();
    Assert.IsFalse(safeHandle.IsInvalid);
    
    safeHandle.Dispose();
    Assert.IsFalse(safeHandle.IsInvalid);

    Why does the second assert succeed? I disposed safe handle yet it still says it is valid.
    Friday, January 15, 2010 10:10 PM

Answers

  • Actually, IsInvalid is a different concept than IsClosed.  It indicates that the handle value is a constant known to represent a bogus handle of that type.  Yep, it varies depending on the handle type.  Invalid handle values in Win32 are a mess.  Raymond Chen's post: http://blogs.msdn.com/oldnewthing/archive/2004/03/02/82639.aspx

    From MSDN: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.isinvalid.aspx

    [quote]
    Unlike the IsClosed property, which reports whether the SafeHandle object has finished using the underlying handle, the IsInvalid property calculates whether the given handle value is always considered invalid. Therefore, the IsInvalid property always returns the same value for any one handle value.
    [/quote]

    The base classes SafeHandleMinusOneIsInvalid and SafeHandleZeroOrMinusOneIsInvalid are provided to help you with the common cases.

    As you can see from this, when you call Close or Dispose, the property you want to check is the IsClosed property.

    Saturday, January 16, 2010 1:04 AM

All replies

  • SafeHandleDerivedClass needs to override IsInvalid correctly.  Typically, this means setting this to true after Dispose() was called.  SafeHandle doesn't implement this behavior - its' up to the derived class to handle this properly.

    Without knowing what specific class you're using, we can't tell you more.
    Reed Copsey, Jr. - http://reedcopsey.com
    Friday, January 15, 2010 10:26 PM
  • Classes in framework from Microsoft.Win32.SafeHandles namespace do not do this. Bug in framework?
    Friday, January 15, 2010 10:36 PM
  • I can do it even simpler by setting base.handle to IntPtr.Zero in ReleaseHandle.
    Friday, January 15, 2010 10:37 PM
  • Actually, IsInvalid is a different concept than IsClosed.  It indicates that the handle value is a constant known to represent a bogus handle of that type.  Yep, it varies depending on the handle type.  Invalid handle values in Win32 are a mess.  Raymond Chen's post: http://blogs.msdn.com/oldnewthing/archive/2004/03/02/82639.aspx

    From MSDN: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.isinvalid.aspx

    [quote]
    Unlike the IsClosed property, which reports whether the SafeHandle object has finished using the underlying handle, the IsInvalid property calculates whether the given handle value is always considered invalid. Therefore, the IsInvalid property always returns the same value for any one handle value.
    [/quote]

    The base classes SafeHandleMinusOneIsInvalid and SafeHandleZeroOrMinusOneIsInvalid are provided to help you with the common cases.

    As you can see from this, when you call Close or Dispose, the property you want to check is the IsClosed property.

    Saturday, January 16, 2010 1:04 AM