FileSystemWatcher网络断开连接

时间:2012-02-06 14:54:06

标签: c# .net filesystemwatcher

我有一个FileSystemWatcher监视网络共享上的文件。如果发生事件以使共享不可用,可能是由于网络问题,FileSystemWatcher将断开连接。

显然我可以处理“错误”事件,可能会做一些日志记录,很多文章都建议在错误事件处理程序中重新连接FSW。

但是,如果网络共享在错误事件中仍然不可用,该怎么办?然后我需要引入一个计时器来测试网络共享是否可用并尝试重新连接FSW。

1)有更好的方法吗?

2)是否有一个属性允许我确定FSW已与文件断开连接?我注意到FSW的一个非公共成员“stopListening”,当FSW断开连接时,它似乎设置为true。但这并未公开曝光

任何帮助将不胜感激......

由于 凯文

3 个答案:

答案 0 :(得分:7)

一些评论和建议......(随着我的打字而变得越来越大......抱歉)

当FileSystemWatcher发生如此之多的事件以至于无法处理所有事件时,会触发FileSystemWatcher.Error事件。在观看文件系统时发生错误(例如网络丢失),不会被触发。

我相信我遇到了类似的情况。问题是,当网络连接断开时,FileSystemWatcher将永远不会触发事件,因为它实际上看不到它应该看的内容,但似乎并没有意识到这一事实。当网络连接恢复时,FileSystemWatcher不会恢复 - 即它仍然无法看到(恢复的)连接。我们提出的唯一可靠的解决方案是使用定时器定期删除整个FileSystemWatcher对象并创建一个新的,设置所有事件和监视文件夹等。因为删除并创建一个新的FileSystemWatcher是(相对)快速(即毫秒)您可以将计时器设置为每10秒左右激活一次,而不会占用过多的处理器。当然,如果网络仍处于运行状态,无论您做什么,FileSystemWatcher都无法看到网络。但是没关系,它将在另外10秒内再试一次。

使用此解决方案需要注意两件事:

  1. 当计时器激活时,需要检查FileSystemWatcher当前是否正在处理任何事件,如果是,则需要等待。所以在timer事件中,停止Timer,停止FileSystemWatcher引发事件,然后等待任何FileSystemWatcher事件完成(使用lock(...){...}这是一个很好的方法)。
  2. 在删除并重新创建FileSystemWatcher之后,您需要手动检查在刷新FileSystemWatcher时(或网络关闭时)可能发生的任何事件。例如,如果您正在查看正在创建的文件,并且在刷新FileSystemWatcher时或在网络连接结束时创建了文件,则在启动FileSystemWatcher的新实例时,您将无法获取这些文件的事件(因为文件已经创建了。)
  3. 我希望有所帮助。

答案 1 :(得分:1)

此后续行动。根据MSDN论坛上的Microsoft资源的建议,我将其添加到Microsoft Connect。

来自微软反馈的要点: - 错误事件不仅适用于内部缓冲区溢出 - 他们将添加将 stopListening 属性公开给他们的客户建议列表的可能性

此处链接:http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

答案 2 :(得分:0)

不会有这样的工作吗?似乎适用于我的简单测试用例。

var fsw = new FileSystemWatcher("[folder]", "*.*") { IncludeSubdirectories = true};
var fsw_processing = false;
fsw.Deleted += (s, e) => 
{
    fsw_processing = true;
    fsw.EnableRaisingEvents = false;
    //......
    fsw.EnableRaisingEvents = true;
    fsw_processing = false;
};    
fsw.Changed += (s, e) => 
{
    fsw_processing = true;
    fsw.EnableRaisingEvents = false;
    //......
    fsw.EnableRaisingEvents = true;
    fsw_processing = false;
};    
//governor thread to check FileSystemWatcher is still connected. 
//It seems to disconnects on network outages etc.
Task.Run(() =>
{
    while (true)
    {
        if (fsw.EnableRaisingEvents == false && fsw_processing == false)
        {                        
            try
            {fsw.EnableRaisingEvents = true;}
            catch (Exception) { fsw.EnableRaisingEvents = false; }            
        }
        System.Threading.Thread.Sleep(1000 * 10);//sleep 10 secs
    }
});