我有一个具有大量静态成员的类,其中一些保留对托管和非托管对象的引用。
例如,一旦引用类型,就会调用静态构造函数,这会导致我的类启动阻塞任务队列。例如,当调用其中一个静态方法时,就会发生这种情况。
我实现了 IDisposable,它为我提供了处理我创建的任何实例对象的方法。但是,如果使用者没有从我的类中创建任何实例对象,则永远不会调用这些方法。
如何以及在哪里放置代码来处理由类的静态部分维护的引用?我一直认为静态引用资源的处置发生在最后一个实例对象被释放时;这是我第一次创建一个不能创建任何实例的类。
在卸载托管类的应用程序域之前,类的静态变量不会被垃圾收集。
Dispose()
方法不会被调用,因为它是一个实例方法,并且你说过你不会创建类的任何实例。
如果您想使用
Dispose()
方法,请使您的对象成为单例,创建它的一个实例,并在应用程序即将退出时显式处置它。
public class MyClass : IDisposable {
public IList List1 {get; private set;}
public IDictionary<string,string> Dict1 {get; private set;}
public void Dispose() {
// Do something here
}
public static MyClass Instance {get; private set;}
static MyClass() {
Instance = new MyClass();
}
public static void DisposeInstance() {
if (Instance != null) {
Instance.Dispose();
Instance = null;
}
}
}
public class Logger : IDisposable
{
private string _logDirectory = null;
private static Logger _instance = null;
private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"])
{
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
}
private Logger(string logDirectory)
{
}
public static Logger Instance
{
get
{
if (_instance == null)
_instance = new Logger();
return _instance;
}
}
private void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
// Dispose unmanaged resources
}
}
您应该手动处置此对象,无法为静态资源创建“终结器”。
如果您确实想要拥有保留对非托管对象的引用的静态成员 只需创建一个方法来处理非托管对象并“强制”消费者在退出时使用它。
我所说的“强制”是指用一段段落来记录您的课程,说明“何时”和“为什么”使用此“处置”方法。 如果您是唯一的消费者(或您的代码...)或者您计划分发您的课程,请执行此操作。 还尝试使用某种描述性名称(对于“dispose”方法),例如“DisposeStatics”、“AlwaysDispose”、“DisposeAtEnd”等。
如果您想维护静态类并且您相信没有人需要了解该类的内部工作原理,您可以在静态类中放置一个带有 IDisposable 的单例类,并将任何需要处理的成员放置在该单例中。然后只需从同名静态成员中引用单例成员即可。
公共静态类 AStaticClass { 公共静态对象 PropertyThatNeedsSpecialDisposal { 获取 { 返回 DisposableInnerClass.Instance.PropertyThatNeedsSpecialDisposal; } }
protected internal class DisposableInnerClass : IDisposable
{
private static readonly object locker = new object();
private static DisposableInnerClass? _instance = null;
private DisposableInnerClass()
{ }
public int PropertyThatNeedsSpecialDisposal = 42;
internal static DisposableInnerClass Instance
{
get
{
if (_instance is null)
{
lock (locker)
{
if (_instance is null)
{
_instance = new DisposableInnerClass();
}
}
}
return _instance;
}
}
public void Dispose()
{
//dispose of PropertyThatNeedsSpecialDisposal here
}
}
}