简体   繁体   English

FileSystemWatcher网络断开连接

[英]FileSystemWatcher Network Disconnect

I have a FileSystemWatcher monitoring a file on a network share. 我有一个FileSystemWatcher监视网络共享上的文件。 If an event occurs to make the share unavailable, maybe due to a network problem, the FileSystemWatcher becomes disconnected. 如果发生事件以使共享不可用,可能是由于网络问题,FileSystemWatcher将断开连接。

Obviously I can handle the "Error" event, maybe do some logging and lots of articles suggest reconnecting the FSW inside the error event handler. 显然我可以处理“错误”事件,也许做一些日志记录,很多文章建议在错误事件处理程序中重新连接FSW。

But what if the network share is still unavailable inside the error event. 但是,如果网络共享在错误事件中仍然不可用,该怎么办? I then need to introduce a timer to test if the network share is available and attempt to reconnect the FSW. 然后我需要引入一个计时器来测试网络共享是否可用并尝试重新连接FSW。

1) Is there a better approach? 1)有更好的方法吗?

2) Is there a property that allows me to determine that the FSW has become disconnected from the file? 2)是否有一个属性允许我确定FSW已与文件断开连接? I notice there is a non-public member of the FSW "stopListening", which appears to be set to true when the FSW becomes disconnected. 我注意到FSW的一个非公共成员“stopListening”,当FSW断开连接时,它似乎设置为true。 But this is not publicly exposed 但这并未公开曝光

Any help would be appreciated ... 任何帮助,将不胜感激 ...

Thanks Kevin 谢谢凯文

A couple of comments and suggestions...(which grew and grew as I was typing...sorry) 一些评论和建议......(随着我的打字而变得越来越大......抱歉)

The FileSystemWatcher.Error event is fired when the FileSystemWatcher gets so many events happening so quickly that it can't handle them all. FileSystemWatcher.Error事件在FileSystemWatcher发生如此之多的事件以至于无法处理所有事件时触发了FileSystemWatcher.Error事件。 It doesn't get fired when an error occurs in watching the file system (such as the network dropping out). 在观察文件系统时发生错误(例如网络丢失),它不会被触发。

I believe I've had a similar situation. 我相信我遇到了类似的情况。 The problem is that when the network connection drops out, the FileSystemWatcher will never have an event triggered, because it actually can't see what it's supposed to be watching, but it doesn't seem to be aware of the fact. 问题是,当网络连接断开时,FileSystemWatcher将永远不会触发事件,因为它实际上看不到它应该看的内容,但似乎并没有意识到这一事实。 When the network connection comes back, the FileSystemWatcher doesn't recover - ie it still can't see the (restored) connection. 当网络连接恢复时,FileSystemWatcher无法恢复 - 即它仍然无法看到(恢复的)连接。 The only solution that we came up with that seemed to work reliably was to have a timer that regularly dropped the whole FileSystemWatcher object and created a new one, setting all of the events and watch folder etc. Since dropping and creating a new FileSystemWatcher is (relatively) quick (ie milliseconds) you could set the timer to activate every 10 seconds or so without using up too much of the processor. 我们提出的唯一可靠的解决方案是使用定时器定期删除整个FileSystemWatcher对象并创建一个新的,设置所有事件和监视文件夹等。因为删除并创建一个新的FileSystemWatcher是(相对)快速(即毫秒)您可以将计时器设置为每10秒左右激活一次,而不会占用过多的处理器。 Of course, if the network is still out, the FileSystemWatcher is not going to be able to see the network no matter what you do. 当然,如果网络仍处于运行状态,无论您做什么,FileSystemWatcher都无法看到网络。 But that's OK, it will try again in another 10 seconds. 但是没关系,它将在另外10秒内再试一次。

Two things to watch out for with this solution: 使用此解决方案需要注意两件事:

  1. When the timer activates, it needs to check that the FileSystemWatcher isn't currently processing any events, and it needs to wait if it is. 当计时器激活时,它需要检查FileSystemWatcher当前是否正在处理任何事件,如果是,则需要等待。 So in the timer event, stop the Timer, stop the FileSystemWatcher from raising events, then wait for any FileSystemWatcher events to finish (using lock (...) {...} is a good way of doing this). 所以在timer事件中,停止Timer,停止FileSystemWatcher引发事件,然后等待任何FileSystemWatcher事件完成(使用lock(...){...}这是一个很好的方法)。
  2. After dropping and recreating the FileSystemWatcher, you need to manually check for any events that might have occurred while the FileSystemWatcher was being refreshed (or while the network was down). 删除并重新创建FileSystemWatcher后,您需要手动检查在刷新FileSystemWatcher时(或网络关闭时)可能发生的任何事件。 For example, if you're watching for files being created, and a file gets created while refreshing the FileSystemWatcher or while the network connection is out, you won't get events for those files when you start up the new instance of the FileSystemWatcher (since the files have already been created). 例如,如果您正在查看正在创建的文件,并且在刷新FileSystemWatcher时或在网络连接结束时创建了文件,则在启动FileSystemWatcher的新实例时,您将无法获取这些文件的事件(因为文件已经创建了)。

I hope that helps. 我希望有所帮助。

Follow-up in this. 这方面的后续行动。 At the suggestion of a Microsoft resource on the MSDN forums, I added this to Microsoft Connect. 根据MSDN论坛上的Microsoft资源的建议,我将此添加到Microsoft Connect。

Key points from the feedback from Microsoft: - Error event is not only for internal buffer overflows - They will add the possibility of exposing the stopListening property to their list of customer suggestions 来自Microsoft反馈的要点: - 错误事件不仅仅是内部缓冲区溢出 - 它们还增加了将stopListening属性暴露给客户建议列表的可能性

Link here: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling 链接到这里: http//connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

Wouldn't something like this work? 不会像这样的工作吗? Seems to work for my simple test case. 似乎适用于我的简单测试用例。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM