FileSystemWatcher Dispose 调用挂起
我们刚刚开始遇到 FileSystemWatcher 的一个奇怪问题,其中对 Dispose() 的调用似乎挂起。 该代码已经运行一段时间了,没有出现任何问题,但我们刚刚升级到 .NET3.5 SP1,所以我试图找出是否有其他人看到过这种行为。 下面是创建 FileSystemWatcher 的代码:
if (this.fileWatcher == null)
{
this.fileWatcher = new FileSystemWatcher();
}
this.fileWatcher.BeginInit();
this.fileWatcher.IncludeSubdirectories = true;
this.fileWatcher.Path = project.Directory;
this.fileWatcher.EnableRaisingEvents = true;
this.fileWatcher.NotifyFilter = NotifyFilters.Attributes;
this.fileWatcher.Changed += delegate(object s, FileSystemEventArgs args)
{
FileWatcherFileChanged(args);
};
this.fileWatcher.EndInit();
使用的方式是更新 TreeNode 对象的状态图像(稍微调整以删除业务特定信息):
private void FileWatcherFileChanged(FileSystemEventArgs args)
{
if (this.TreeView != null)
{
if (this.TreeView.InvokeRequired)
{
FileWatcherFileChangedCallback d = new FileWatcherFileChangedCallback(FileWatcherFileChanged);
this.TreeView.Invoke(d, new object[]
{
args
});
}
else
{
switch (args.ChangeType)
{
case WatcherChangeTypes.Changed:
if (String.CompareOrdinal(this.project.FullName, args.FullPath) == 0)
{
this.StateImageKey = GetStateImageKey();
}
else
{
projectItemTreeNode.StateImageKey = GetStateImageKey();
}
break;
}
}
}
}
是否有我们遗漏的东西,或者这是 .NET3 的异常现象.5 SP1?
We just started running in to an odd problem with a FileSystemWatcher where the call to Dispose() appears to be hanging. This is code that has been working without any problems for a while but we just upgraded to .NET3.5 SP1 so I'm trying to find out if anyone else has seen this behavior. Here is the code that creates the FileSystemWatcher:
if (this.fileWatcher == null)
{
this.fileWatcher = new FileSystemWatcher();
}
this.fileWatcher.BeginInit();
this.fileWatcher.IncludeSubdirectories = true;
this.fileWatcher.Path = project.Directory;
this.fileWatcher.EnableRaisingEvents = true;
this.fileWatcher.NotifyFilter = NotifyFilters.Attributes;
this.fileWatcher.Changed += delegate(object s, FileSystemEventArgs args)
{
FileWatcherFileChanged(args);
};
this.fileWatcher.EndInit();
The way this is being used is to update the state image of a TreeNode object (adjusted slightly to remove business specific information):
private void FileWatcherFileChanged(FileSystemEventArgs args)
{
if (this.TreeView != null)
{
if (this.TreeView.InvokeRequired)
{
FileWatcherFileChangedCallback d = new FileWatcherFileChangedCallback(FileWatcherFileChanged);
this.TreeView.Invoke(d, new object[]
{
args
});
}
else
{
switch (args.ChangeType)
{
case WatcherChangeTypes.Changed:
if (String.CompareOrdinal(this.project.FullName, args.FullPath) == 0)
{
this.StateImageKey = GetStateImageKey();
}
else
{
projectItemTreeNode.StateImageKey = GetStateImageKey();
}
break;
}
}
}
}
Is there something we're missing or is this an anomoly from .NET3.5 SP1?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我们也遇到这个问题。 我们的应用程序在.Net 2.0 上运行,但由 VS 2008 SP1 编译。 我也安装了.NET 3.5 SP1。 我也不知道为什么会发生这种情况,它看起来不像我们这边的死锁问题,因为此时没有其他线程正在运行(它是在应用程序关闭期间)。
We are also having this issue. Our application runs on .Net 2.0 but is compiled by VS 2008 SP1. I have .NET 3.5 SP1 installed as well. I've got no idea why this happens either, it doesn't look like a deadlock issue on our end as no other threads are running at this point (it is during application shutdown).
Scott,我们偶尔会在 .NET 2 中看到 control.Invoke 的问题。尝试切换到 control.BeginInvoke 并看看是否有帮助。
这样做将允许 FileSystemWatcher 线程立即返回。 我怀疑您的问题是 control.Invoke 阻塞,从而导致 FileSystemWatcher 在处置时冻结。
Scott, we've occasionally seen issues with control.Invoke in .NET 2. Try switching to control.BeginInvoke and see if that helps.
Doing that will allow the FileSystemWatcher thread to return immediately. I suspect your issue is somehow that the control.Invoke is blocking, thus causing the FileSystemWatcher to freeze upon dispose.
只是一个想法...这里有可能存在僵局问题吗?
您正在调用 TreeView.Invoke,这是一个阻塞调用。 如果在您单击导致 FileSystemWatcher.Dispose() 调用的任何按钮时发生文件系统更改,则您的 FileWatcherFileChanged 方法将在后台线程上调用并调用 TreeView.Invoke,这将阻塞,直到您的表单线程可以处理 Invoke 请求。 但是,您的表单线程将调用 FileSystemWatcher.Dispose(),在处理所有挂起的更改请求之前,它可能不会返回。
尝试将 .Invoke 更改为 .BeginInvoke 并查看是否有帮助。 这可能会帮助您指明正确的方向。
当然,也可能是.NET 3.5SP1问题。 我只是根据您提供的代码在这里推测。
Just a thought... Any chance there's a deadlock issue here?
You're calling TreeView.Invoke, which is a blocking call. If a filesystem change happens just as you're clicking whatever button causes the FileSystemWatcher.Dispose() call, your FileWatcherFileChanged method will get called on a background thread and call TreeView.Invoke, which will block until your form thread can process the Invoke request. However, your form thread would be calling FileSystemWatcher.Dispose(), which probably doesn't return until all pending change requests are processed.
Try changing the .Invoke to .BeginInvoke and see if that helps. That may help point you in the right direction.
Of course, it could also be a .NET 3.5SP1 issue. I'm just speculating here based on the code you provided.