注册FileSystemWatcher
上的事件会导致注册类在取消FileSystemWatcher
的所有(我的)引用并让GC和终结器运行后保留在内存中。我在下面构建了一个示例,展示了使用FileSystemWatcher
的对象如何保留在内存中,而使用类似事件/事件处理程序的另一组对象(类型A
和B
)则没有留在记忆中。
示例
class Program
{
class UsesFileWatcher
{
public FileSystemWatcher fw;
public UsesFileWatcher()
{
fw = new FileSystemWatcher(@"C:\", "*.txt");
fw.Changed += eventHandler;
fw.EnableRaisingEvents = true;
}
void eventHandler(object sender, FileSystemEventArgs e)
{
}
}
// For Comparison, I have classes A and B which use similar events and event handlers
class A
{
public event EventHandler AEvent;
}
class B
{
public A a;
public B()
{
a = new A();
a.AEvent += eventHandler;
}
void eventHandler(object sender, EventArgs e)
{
}
}
static void Main(string[] args)
{
var weakRefToB = WeakReferenceToB();
var weakRefToUsesFileWatcher = WeakReferenceToUsesFileWatcher();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("B Alive = {0}", weakRefToB.IsAlive);
Console.WriteLine("UsesFileWatcher Alive = {0}", weakRefToUsesFileWatcher.IsAlive);
Console.ReadKey();
}
static WeakReference WeakReferenceToB()
{
return new WeakReference(new B());
}
static WeakReference WeakReferenceToUsesFileWatcher()
{
return new WeakReference(new UsesFileWatcher());
}
}
备注:
我知道FileSystemWatcher实现了IDisposable
,并且当我完成它时我应该调用Dispose()
。但我的理解是,如果我错过了对Dispose()
的调用,那就意味着它需要做的工作将在终结期间完成。
记录了here已知的FileSystemWatcher内存泄漏。但这种描述听起来与我所描述的不同。
我使用Red Gate的ANTS Memory Profiler来显示保持活着的原因:
问题:
这是FileSystemWatcher
中的错误还是我的期望不正确?
答案 0 :(得分:-1)
当然,这不是一个错误。您可以在分析器中看到正在引用该对象。有一个根系的系统类型,它有一个FSW回调,使其可以从一个有根的对象访问。
它将在处理时删除这些回调,使其能够被收集,因此如果您希望它有资格收集,您将需要处置它。