How do I handle the release of unmanaged structures when the application is closed?

I have a C # project in which I am using several unmanaged C ++ functions. What's more, I also have a static IntPtr that I use as parameters for these functions. I know that whenever I use them I have to implement IDisposable in this class and use the destructor to call the Dispose method where I release the used IntPtr as stated on the MSDN page.

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
    // Check to see if Dispose has already been called.
    if (!this.disposed)
    {
        if (disposing)
        {
            component.Dispose();
        }

        CloseHandle(m_InstanceHandle);
        m_InstanceHandle = IntPtr.Zero;

        disposed = true;

    }
}

[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);

      

However, when I terminate the application, I am still left hanging in the TaskManager. I believe this should be due to the use of MarshalAs statement in my structures:

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
 public struct SipxAudioCodec
 {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
        public string CodecName;
        public SipxAudioBandwidth Bandwidth;
        public int PayloadType;
 }

      

When I create a structure like this, should I also be careful to free up the space it allocates using a destructor?

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
 public struct SipxAudioCodec
 {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
        public string CodecName;
        public SipxAudioBandwidth Bandwidth;
        public int PayloadType;

        ~SipxAudioCodec()
        {
            Marshal.FreeGlobal(something...);
        }
 }

      

+2


a source to share


2 answers


The correct way to handle IntPtr

-style handles in p / Invoke interop is:

  • Define the class SafeMyHandle

    derived from SafeHandle

    . He has only to redefine IsInvalid

    and ReleaseHandle

    doing nothing.
  • Define another class MyHandle

    that has public API methods for this handle.
  • MyHandle

    must have a private member of the type SafeMyHandle

    .
  • MyHandle

    should implement IDisposable

    and the method Dispose

    should just be called SafeMyHandle.Dispose

    .
  • All p / Invoke methods should not be used IntPtr

    directly; rather, they must pass and return instances SafeMyHandle

    . The only exception is the "release function", which is called from SafeMyHandle.ReleaseHandle

    ; he must accept IntPtr

    .


If you follow these conventions, your descriptors will be deallocated even if your AppDomain is rudely torn.

+1


a source


I've had cases in the past where an application would hang after closing, usually because not all threads were interrupted. How do I terminate my application? Could it be a problem?



0


a source







All Articles