FileSystemWatcher的对文件的列表 [英] FileSystemwatcher for a list of files

查看:234
本文介绍了FileSystemWatcher的对文件的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注 FileSystemWatcher的Changed事件引发莅临指导的两倍



不过,我有我看着那么如果我删除20个文件一起被称为20次事件的文件列表。这是预期和正常工作。



我怎么只能有一个事件20同时文件更改触发一次(即我怎么能忽略所有其他文件更改,直到在调用onChanged 下面的第一个实例代码已经完成。现在调用onChanged 被称为20倍。)?

 私人无效Main_Load(对象发件人,EventArgs五)
{
公共静态列表< FileSystemWatcher的>观察家=新的List<&FileSystemWatcher的GT;();
UpdateWatcher();
}


公共无效调用onChanged(对象发件人,FileSystemEventArgs E)
{

{
Logging.Write_To_Log_File( 项目的变化来检测+ e.ChangeType ++ e.FullPath ++ e.Name,MethodBase.GetCurrentMethod()。名称,,,,,,, 2);
watchers.Clear();

的foreach(在MyGlobals.watchers FileSystemWatcher的元素)
{
element.EnableRaisingEvents = FALSE;
}

//难道我的文件,这里....
返回列表上的一些处理;

}
赶上(异常前)
{
//如果发生异常时,它会在这里返回
}
终于
{
的foreach(在MyGlobals.watchers FileSystemWatcher的元素)
{
element.EnableRaisingEvents = TRUE;
}
}
}





公共无效UpdateWatcher()//检查项目
{


{
watchers.Clear();

的for(int i = 0; I< MyGlobals.ListOfItemsToControl.Count;我++)//循环遍历目录与
{
FileSystemWatcher的W =新FileSystemWatcher的();
w.Path = Path.GetDirectoryName(MyGlobals.ListOfItemsToControl [I] .sItemName); //文件路径
w.Filter = Path.GetFileName(MyGlobals.ListOfItemsToControl [I] .sItemName); //文件名
w.Changed + =新FileSystemEventHandler(调用onChanged);
w.Deleted + =新FileSystemEventHandler(调用onChanged);
w.Created + =新FileSystemEventHandler(调用onChanged);
w.EnableRaisingEvents = TRUE;
watchers.Add(重量);
}
}
赶上(异常前)
{
//如果发生异常时,它会在这里返回

}
}


解决方案

这里的关键点是什么呢一起对你意味着什么。所有的系统确实为每一个独立的删除操作后,这将在技术上意味着在相同的时间,他们是不是都被删除,但如果你只是想接近,让我们说,如果他们都在对方5秒内删除,那么我们只是想的OnChange火一次,你可以做以下。请注意,这不处理重命名更改通知。你没有监听的,所以我以为你并不需要。



您可能会想改变话,5秒窗口取决于您使用的小窗口。

 类SlowFileSystemWatcher:FileSystemWatcher的
{
公众委托无效SlowFileSystemWatcherEventHandler(对象发件人,FileSystemEventArgs参数);

公共事件SlowFileSystemWatcherEventHandler SlowChanged;
公众的DateTime LastFired {搞定;私人集; }

公共SlowFileSystemWatcher(字符串路径)
:基地(路径)
{
变更+ = HandleChange;
创建+ = HandleChange;
+删除= HandleChange;
LastFired = DateTime.MinValue;
}

私人无效SlowGeneralChange(对象发件人,FileSystemEventArgs参数)
{
如果(LastFired.Add(TimeSpan.FromSeconds(5))< D​​ateTime.UtcNow )
{
SlowChanged.Invoke(发件人,参数);
LastFired = DateTime.UtcNow;
}
}

私人无效HandleChange(对象发件人,FileSystemEventArgs参数)
{
SlowGeneralChange(发件人,参数);
}

保护覆盖无效的Dispose(BOOL处置)
{
SlowChanged = NULL;
base.Dispose(处置);
}
}


I have been following the guidance here FileSystemWatcher Changed event is raised twice.

However I have a list of files that I'm watching so if I delete 20 files together the event is called 20 times. This is expected and works fine.

How can I only have an event fired once for 20 "simultaneous" file changes (i.e How can I ignore all other file changes until the code in the first instance of Onchanged below has completed. Right now Onchanged is called 20 times.) ?

private void Main_Load(object sender, EventArgs e)
{
    public static List<FileSystemWatcher> watchers = new List<FileSystemWatcher>();
    UpdateWatcher();
}


public void OnChanged(object sender, FileSystemEventArgs e)
{
    try
    {
      Logging.Write_To_Log_File("Item change detected " + e.ChangeType + " " + e.FullPath + " " + e.Name, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2);
      watchers.Clear();

      foreach (FileSystemWatcher element in MyGlobals.watchers)
      {
        element.EnableRaisingEvents = false;
      }

      //Do some processing on my list of files here....
      return;

    }    
    catch (Exception ex)
    {
       // If exception happens, it will be returned here
    }                
    finally
    {
         foreach (FileSystemWatcher element in MyGlobals.watchers)
         {
            element.EnableRaisingEvents = true;
         }
    }
}





public void UpdateWatcher() // Check Items
        {

        try
        {
        watchers.Clear();

        for (int i = 0; i < MyGlobals.ListOfItemsToControl.Count; i++) // Loop through List with for
        {
        FileSystemWatcher w = new FileSystemWatcher();
         w.Path = Path.GetDirectoryName(MyGlobals.ListOfItemsToControl[i].sItemName); // File path    
        w.Filter = Path.GetFileName(MyGlobals.ListOfItemsToControl[i].sItemName); // File name
        w.Changed += new FileSystemEventHandler(OnChanged);
        w.Deleted += new FileSystemEventHandler(OnChanged);
        w.Created += new FileSystemEventHandler(OnChanged);
        w.EnableRaisingEvents = true;
        watchers.Add(w);
        }
        }
        catch (Exception ex)
        {
        // If exception happens, it will be returned here

        }
        }

解决方案

The key point here is what does "together" mean to you. after all the system does an independent delete operation for each, which would technically mean they are not all deleted at the exact same time, but if you just wanna be close, let's say if they are all deleted within 5 seconds of each other then we only want OnChange to fire once, you can do the following. Note that this doesn't handle the rename change notification. You weren't listening for it, so I assumed you don't need to.

you may wanna change the 5 seconds window to a small window depending on your use.

    class SlowFileSystemWatcher : FileSystemWatcher
    {
        public delegate void SlowFileSystemWatcherEventHandler(object sender, FileSystemEventArgs args);

        public event SlowFileSystemWatcherEventHandler SlowChanged;
        public DateTime LastFired { get; private set; }

        public SlowFileSystemWatcher(string path)
            : base(path)
        {
            Changed += HandleChange;
            Created += HandleChange;
            Deleted += HandleChange;
            LastFired = DateTime.MinValue;
        }

        private void SlowGeneralChange(object sender, FileSystemEventArgs args)
        {
            if (LastFired.Add(TimeSpan.FromSeconds(5)) < DateTime.UtcNow)
            {
                SlowChanged.Invoke(sender, args);
                LastFired = DateTime.UtcNow;
            }
        }

        private void HandleChange(object sender, FileSystemEventArgs args)
        {
            SlowGeneralChange(sender, args);
        }

        protected override void Dispose(bool disposing)
        {
            SlowChanged = null;
            base.Dispose(disposing);
        }
    }

这篇关于FileSystemWatcher的对文件的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆