尽管采取了相应的措施,FileSystemWatcher事件仍然举两次

时间:2014-03-31 16:45:30

标签: c# .net filesystemwatcher

我在这里和其他网站浏览了不少线程,以解决此问题。

这是我的FileMonitor类:

class FileMonitor
{
    public FileMonitor(String path)
    {
        try
        {
            var watcher = new FileSystemWatcher()
            {
                Path = path,
                IncludeSubdirectories = true,
                InternalBufferSize = 65536,
                EnableRaisingEvents = true
            };

            watcher.Changed += new FileSystemEventHandler(OnFileChanged);
            watcher.Created += new FileSystemEventHandler(OnFileCreated);
            watcher.Deleted += new FileSystemEventHandler(OnFileDeleted);
            watcher.Renamed += new RenamedEventHandler(OnFileRenamed);
            watcher.Error += new ErrorEventHandler(OnWatcherError);
        }
        catch (Exception)
        {

            throw;
        }
    }

    private void OnWatcherError(object sender, ErrorEventArgs e)
    {

    }

    private void OnFileChanged(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileCreated(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileDeleted(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileRenamed(object sender, RenamedEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemRenaming(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void LogFileSystemChanges(FileSystemEventArgs e)
    {
        string log = string.Format("{0:G}: {1} | {2}", DateTime.Now, e.FullPath, e.ChangeType);
        Console.WriteLine(log);
    }

    private void LogFileSystemRenaming(RenamedEventArgs e)
    {
        string log = string.Format("{0:G}: {1} | Old name: {2}", DateTime.Now, e.FullPath, e.OldName);
        Console.WriteLine(log);
    }
}

正如你所知,我已尝试((FileSystemWatcher)sender).EnableRaisingEvents = false;的“锁定”,但我可以从我的控制台输出告诉我的事件是否触发了两次。

有关于此的任何想法吗?我真的不确定从哪里开始。

2 个答案:

答案 0 :(得分:6)

我遇到了同样的问题,经过多次讨论后, Notepad 在行中写了三次(!)文件。如果一个应用程序真的经常保存(可能是为了对备份进行三角测量等),那么你无能为力。

我还注意到你已经附加了所有事件,你应该将其缩小到最不需要的范围,并使用NotifyFilters过滤掉你不感兴趣的事件。

答案 1 :(得分:3)

我之前尝试过使用 FileSystemWatcher 类(许多年前结果是 - 2008),并且遇到了重大问题。最多只有 leaky abstraction 。我当时在CodeProject上报告了我的发现。在评论列表中查找“Glytzhkof”。我记得我几乎在班级的每个方面都遇到了问题,但在这么多年之后它可能已经有了改进

总之,我在当天的经历是,事件完全消失或堆积,导致基于变量的异常,例如是否启用了磁盘的写入缓存,是否访问了RAID,NAS或常规磁盘,以及其他随机硬件问题我不记得确切。有趣的是,似乎它与UNC路径一起工作。不知道为什么。映射驱动器失败。

查看summary in the Code Project discussion。我确信自从我尝试以来有一些改进,也许还有一些新的错误:-)。磁盘存储硬件似乎很难作为高级抽象来处理 - it leaks。就个人而言,我最终使用服务和常规磁盘功能手动扫描文件。在手动做事之前我浪费了很多时间。

更新:点击此处查看新信息:https://stackoverflow.com/a/23704476/129130