文件系统监视器网络断开

12

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

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

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

1)是否有更好的方法?

2)是否有一个属性可以让我确定FSW已经与文件断开连接?我注意到FSW的一个非公共成员“stopListening”,当FSW断开连接时似乎被设置为true。但这不是公开的。

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

谢谢 Kevin


感谢您的回复Erno,但不是这样的。我知道我可以使用Error事件来重新连接。但是当Error事件被触发时,如果网络共享不可用会发生什么?除非我有某种计时器/定时尝试重新连接,否则我没有其他事件可以尝试重新连接!此外,FSW不公开任何属性告诉我它已断开连接。 - Kevin Higgins
根据我提出的帖子,您可以使用错误事件。而定时器是探测可用性的好方法。 - Emond
3个回答

9
一些评论和建议...(我在打字的时候一直在增加,抱歉)
当FileSystemWatcher接收到太多事件而无法处理它们时,会触发FileSystemWatcher.Error事件。它不会在监视文件系统时出现错误(例如网络中断)时触发。
我认为我也遇到过类似的情况。问题在于当网络连接断开时,FileSystemWatcher将永远不会触发事件,因为它实际上无法看到它应该监视的内容,但似乎并没有意识到这一点。当网络连接恢复时,FileSystemWatcher不会恢复——即它仍然无法看到(已恢复的)连接。我们想出来的唯一可靠的解决方案是定时器定期删除整个FileSystemWatcher对象并创建一个新的对象,设置所有事件和监视文件夹等。由于删除和创建新的FileSystemWatcher相对较快(即毫秒级),因此您可以将定时器设置为每10秒激活一次,而不会使用太多的处理器。当然,如果网络仍然断开,无论做什么FileSystemWatcher都无法看到网络。但没关系,它会在另外的10秒内再次尝试。
请注意以下两点: 1.当定时器激活时,需要检查FileSystemWatcher是否正在处理任何事件,并且如果正在处理,则需要等待。所以在定时器事件中,停止计时器,停止FileSystemWatcher触发事件,然后等待任何FileSystemWatcher事件完成(使用lock (...) {...}是一个不错的方法)。 2.在删除和重新创建FileSystemWatcher之后,需要手动检查可能在刷新FileSystemWatcher(或网络断开)期间发生的任何事件。例如,如果您正在监视文件的创建,并且在刷新FileSystemWatcher或网络连接断开时创建了一个文件,则在启动新的FileSystemWatcher实例时,您将无法获取这些文件的事件(因为文件已经被创建)。
希望这能有所帮助。

感谢您的回复,马克。重新阅读MSDN文档后,我发现您是正确的,当监视文件系统时发生错误时,实际上不会触发错误事件,这是我的误解。 - Kevin Higgins
1
你的方法很有趣,但是(可能由于设计缺陷),FileSystemWatcher实际上是一个静态对象,位于高负载WCF服务内部。因此,每10秒重新初始化它的概念对我们来说可能不是一个选项,即使轻微的性能损失也可能对我们所需的响应时间造成昂贵的代价。看起来似乎没有答案,因为我们不能绝对依赖错误事件,最佳解决方案是重构我们的解决方案以删除FileSystemWatcher,因为它似乎是一种不可靠的方法。 - Kevin Higgins

1

2
该页面已不可用或无权查看,这使得答案毫无意义 :( - Darren Wainwright
链接仍然无效,但我也不认为这真的是对你的问题的答案。 - topshot

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
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接