C# 对于具有非托管静态实例的静态类,最佳模式是什么?

C# 对于具有非托管静态实例的静态类,最佳模式是什么?,c#,C#,考虑以下伪代码 static class Tools { static readonly UnmanagedType ut = new UnmanagedType (); } 对于这个场景,什么样的最佳模式可以保证非托管静态实例在应用程序退出后立即释放到系统中 我的大致想法是,在Tools类中实例化ut之后,立即强制订阅Tools处理方法到系统的关闭事件。可能吗?怎么做?单身 sealed class Tools { public static readonly Tools I

考虑以下伪代码

static class Tools
{
    static readonly UnmanagedType ut = new UnmanagedType ();
}
对于这个场景,什么样的最佳模式可以保证非托管静态实例在应用程序退出后立即释放到系统中

我的大致想法是,在
Tools
类中实例化
ut
之后,立即强制订阅
Tools
处理方法到系统的关闭事件。可能吗?怎么做?

单身

sealed class Tools
{
    public static readonly Tools Instance = new Tools();

    private UnmanagedType ut = new UnmanagedType ();

    ~Tools() {
      // TODO: destroy this.ut
    }
}
单身汉

sealed class Tools
{
    public static readonly Tools Instance = new Tools();

    private UnmanagedType ut = new UnmanagedType ();

    ~Tools() {
      // TODO: destroy this.ut
    }
}

我已经看到了一些类似问题的答案(例如,“一旦进程退出,如何在静态类中释放/处置对象/资源”)。所有答案基本上都表明 a) C#中的静态类不能有析构函数(这是正确的), b) 因此,您不能在静态类生命结束时释放资源, c) 因此,您必须将类转换为非静态类来处理/释放对象/资源

我不同意b)和c)项,并建议在退出时处理静态类中的对象的以下解决方案:

  • 在静态类构造函数中或对创建要处置的对象的方法的任何第一次调用中:

    a) 保存主进程线程引用(
    thread.CurrentThread

    b) 启动一个新线程(监视程序),监视主线程是否正在运行

  • 主线程死后,观察者将处理/释放对象/资源并退出
  • 示例代码:

    using System.Threading;
    
    public static class StaticDisposer 
    {
        private static Thread mParentProcThread = null;
        private static Thread mDisposerThread = null;
      // Other class members:
            ………………………………………………
    
      // Objects to be disposed at the process exit:
      // Ex.: private/public static … obj1ToDispose = null;
            ………………………………………………
    
        static StaticDisposer()
        {
             mParentProcThread = Thread.CurrentThread;
             mDisposerThread = new Thread(DisposerThreadBody);
             mDisposerThread.Start();
        }
    
      // Methods of the class:
            ………………………………………………
    
        private static void DisposerThreadBody()
        {
            while (mParentProcThread != null && mParentProcThread.IsAlive)
            {
                Thread.Sleep(500);
            }
            // Dispose objects, release resources, close streams, delete temporary files, etc.:
            //if(obj1ToDispose != null)
            //    <Dispose code>
            //   ………………………………………………………………………………
        }
    
    }
    
    使用系统线程;
    公共静态类静态处理器
    {
    私有静态线程mParentProcThread=null;
    私有静态线程mDisposerThread=null;
    //其他班级成员:
    ………………………………………………
    //要在进程出口处处置的对象:
    //例如:私有/公共静态…obj1ToDispose=null;
    ………………………………………………
    静态处理器()
    {
    mParentProcThread=Thread.CurrentThread;
    MDISPorThread=新线程(处理器线程体);
    mDisposerThread.Start();
    }
    //课程方法:
    ………………………………………………
    私有静态void处理器线程体()
    {
    while(mParentProcThread!=null&&mParentProcThread.IsAlive)
    {
    睡眠(500);
    }
    //处置对象、释放资源、关闭流、删除临时文件等:
    //if(obj1ToDispose!=null)
    //    
    //   ………………………………………………………………………………
    }
    }
    

    NB如果程序中有多个线程正在使用静态类和建议的处理逻辑,并且希望仅在主线程停止时才进行处理,然后,主线程必须在次线程之前调用/设置/获取静态类的任何方法/属性。

    对于类似的问题,我已经看到了一些答案(例如,“一旦进程退出,如何释放/处置静态类中的对象/资源”)。所有答案基本上都表明 a) C#中的静态类不能有析构函数(这是正确的), b) 因此,您不能在静态类生命结束时释放资源, c) 因此,您必须将类转换为非静态类来处理/释放对象/资源

    我不同意b)和c)项,并建议在退出时处理静态类中的对象的以下解决方案:

  • 在静态类构造函数中或对创建要处置的对象的方法的任何第一次调用中:

    a) 保存主进程线程引用(
    thread.CurrentThread

    b) 启动一个新线程(监视程序),监视主线程是否正在运行

  • 主线程死后,观察者将处理/释放对象/资源并退出
  • 示例代码:

    using System.Threading;
    
    public static class StaticDisposer 
    {
        private static Thread mParentProcThread = null;
        private static Thread mDisposerThread = null;
      // Other class members:
            ………………………………………………
    
      // Objects to be disposed at the process exit:
      // Ex.: private/public static … obj1ToDispose = null;
            ………………………………………………
    
        static StaticDisposer()
        {
             mParentProcThread = Thread.CurrentThread;
             mDisposerThread = new Thread(DisposerThreadBody);
             mDisposerThread.Start();
        }
    
      // Methods of the class:
            ………………………………………………
    
        private static void DisposerThreadBody()
        {
            while (mParentProcThread != null && mParentProcThread.IsAlive)
            {
                Thread.Sleep(500);
            }
            // Dispose objects, release resources, close streams, delete temporary files, etc.:
            //if(obj1ToDispose != null)
            //    <Dispose code>
            //   ………………………………………………………………………………
        }
    
    }
    
    使用系统线程;
    公共静态类静态处理器
    {
    私有静态线程mParentProcThread=null;
    私有静态线程mDisposerThread=null;
    //其他班级成员:
    ………………………………………………
    //要在进程出口处处置的对象:
    //例如:私有/公共静态…obj1ToDispose=null;
    ………………………………………………
    静态处理器()
    {
    mParentProcThread=Thread.CurrentThread;
    MDISPorThread=新线程(处理器线程体);
    mDisposerThread.Start();
    }
    //课程方法:
    ………………………………………………
    私有静态void处理器线程体()
    {
    while(mParentProcThread!=null&&mParentProcThread.IsAlive)
    {
    睡眠(500);
    }
    //处置对象、释放资源、关闭流、删除临时文件等:
    //if(obj1ToDispose!=null)
    //    
    //   ………………………………………………………………………………
    }
    }
    

    NB如果程序中有多个线程正在使用静态类和建议的处理逻辑,并且希望仅在主线程停止时进行处理,则主线程必须在次线程之前调用/设置/获取静态类的任何方法/属性。

    但它不是静态类。:-)是的,我故意删除了它,因为静态类不能有析构函数。但它不是静态类。:-)是的,我故意删除了它,因为静态类不能有析构函数。这是不必要的,静态变量引用的对象在程序退出时被最终确定。如何用新操作符实例化“非托管类型”是非常模糊的。若那个段代码可以工作,那个么它也可以有一个终结器。这是不必要的,静态变量引用的对象在程序中被终结