C# 如何在应用程序关闭时释放非托管结构? 我有一个C项目,其中我使用了一些非托管C++函数。 更重要的是,我还有静态IntPtr,我将其用作这些函数的参数。我知道,无论何时使用它们,我都应该在该类中实现IDisposable,并使用析构函数调用Dispose方法,在该方法中释放使用过的IntPtr,如MSDN页面中所述 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);

C# 如何在应用程序关闭时释放非托管结构? 我有一个C项目,其中我使用了一些非托管C++函数。 更重要的是,我还有静态IntPtr,我将其用作这些函数的参数。我知道,无论何时使用它们,我都应该在该类中实现IDisposable,并使用析构函数调用Dispose方法,在该方法中释放使用过的IntPtr,如MSDN页面中所述 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);,c#,unmanaged,structure,C#,Unmanaged,Structure,但是,当我终止应用程序时,TaskManager中仍有一个挂起的进程。我相信这一定与我的结构中MarshalAs指令的使用有关: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct SipxAudioCodec { [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string CodecNam

但是,当我终止应用程序时,TaskManager中仍有一个挂起的进程。我相信这一定与我的结构中MarshalAs指令的使用有关:

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
 public struct SipxAudioCodec
 {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
        public string CodecName;
        public SipxAudioBandwidth Bandwidth;
        public int PayloadType;
 }
当我创建这样一个结构时,我是否也应该小心使用析构函数释放它分配的空间

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

在过去,我曾遇到过应用程序在关闭后挂起的情况,通常是因为并非所有线程都被终止。如何终止应用程序?可能是线程造成的?

在p/Invoke interop中处理
IntPtr
样式句柄的正确方法是:

  • 定义从
    SafeHandle
    派生的类
    SafeMyHandle
    。它应该只覆盖
    IsInvalid
    ReleaseHandle
    ,而不做其他事情
  • 定义另一个类
    MyHandle
    ,该类具有用于该句柄的公共API的方法
  • MyHandle
    应具有类型为
    SafeMyHandle
    的私有成员
  • MyHandle
    应该实现
    IDisposable
    ,其
    Dispose
    方法应该只调用
    SafeMyHandle.Dispose
  • 所有的p/Invoke方法都不应该直接使用
    IntPtr
    ;相反,它们应该传递并返回
    SafeMyHandle
    的实例。一个例外是从SafeMyHandle.ReleaseHandle调用的“释放函数”;它应该使用
    IntPtr

如果您遵循这些约定,即使您的AppDomain被粗暴地拆下,您的句柄也将被释放。

您确定应用程序关闭时确实调用了Dispose方法吗?