C# 通过序列化支持的单例类

C# 通过序列化支持的单例类,c#,windows,serialization,singleton,C#,Windows,Serialization,Singleton,我正在编写一个访问列表的单例类。当第一次初始化单例时,通过对xml文件进行反序列化来填充此列表 这一切都很好,但我希望这个列表是可更新的,为了做到这一点,我目前必须重新序列化每次我添加或删除它 我更希望在从内存中删除对象时,只调用一次来序列化列表。但是,我觉得尝试在~Destructor中执行此操作可能会导致数据丢失等 实现这种行为的最佳模式是什么 P> > C++析构函数C中的析构函数。它们不是在完全正确的对象(不再需要)上运行的实际析构函数,而是处理非托管资源()的最后手段: 对于使用非托

我正在编写一个访问列表的单例类。当第一次初始化单例时,通过对xml文件进行反序列化来填充此列表

这一切都很好,但我希望这个列表是可更新的,为了做到这一点,我目前必须重新序列化每次我添加或删除它

我更希望在从内存中删除对象时,只调用一次来序列化列表。但是,我觉得尝试在~Destructor中执行此操作可能会导致数据丢失等

实现这种行为的最佳模式是什么

<> P> > C++析构函数C中的析构函数。它们不是在完全正确的对象(不再需要)上运行的实际析构函数,而是处理非托管资源()的最后手段:

对于使用非托管资源的类,应该重写Finalize 例如必须释放的文件句柄或数据库连接 在垃圾回收期间丢弃使用它们的托管对象时 收藏

因此,使用与托管资源互操作是一个坏主意,因为:

两个对象的终结器不能保证以任何方式运行 特定顺序,即使一个对象引用另一个对象。也就是说,如果 对象A有一个对对象B的引用,两者都有终结器Object 当对象A的终结器 开始

反序列化的数据列表可能在这样的终结过程中是正确的,或者它可能在以前的GC运行期间已经被回收。即使当前的垃圾收集器不是这样,也没有人能保证这样的问题不会出现在下一个.NET版本中。访问终结器中的托管资源实际上是一种未定义的行为

可能的解决方案

考虑到您的对象是单例对象,因此只有当应用程序退出时才能对其进行垃圾收集(或者,如果从未请求,则从不进行垃圾收集), 允许对对象数据进行这种持久存储的最简单方法是将事件处理程序附加到对象


或者,如果您的单例是基于其使用情况,则使用适当的方法。

可能使用IDisposable?我会让调用方显式调用Save();
...
public static Singleton Instance
{
     get
     {
         if (_Instance == null)         
         {
             _Instance = new Singleton();
             Application.Exit += (sender, args) =>
             {
                 _Instance.SaveChanges();
             }
         }

         return _Instance;
     }
}