C# FileSystemWatcher 组件应用

    在ScheduledJob专案中,要用到很多自定义的DLL组件,为了保证运行的效能,我们采用“缓存”的方式对这些组件进行事先加载,待应用时在内存中既可找到对应的组件并运行,而无需每次都Load. 而这些组件随时都可能有异动,可能新增,可能修改,此时要保证缓存的内容也及时更新,就必须采取一种机制保证,这些组件表更时,能同时更新到内存缓存中。

    在C#中我们可以采用FileSystemWatcher组件实现。

using System;

using System.Collections.Generic;

using System.IO;



namespace fileSystemWatcherDemo

{

    /// <summary>

    /// FileSystemWatcher 组件应用Demo 1

    /// </summary>

    class fileSystemWatcherDemo

    {

        private FileSystemWatcher dllWatcher;



        static void Main(string[] args)

        {

            Console.WriteLine("file Watcher Started  at " + DateTime.Now.ToString());



            fileSystemWatcherDemo watcher = new fileSystemWatcherDemo();

            watcher.beginWatcher();



            Console.Read();

        }



        private void beginWatcher()

        {

            dllWatcher = new FileSystemWatcher();

            dllWatcher.Path = @"D:\ScheduledJob\DLL";

            dllWatcher.IncludeSubdirectories = false;

            dllWatcher.Filter = "*.*";

            dllWatcher.NotifyFilter = NotifyFilters.LastWrite;

            dllWatcher.EnableRaisingEvents = true;

            dllWatcher.Changed += new FileSystemEventHandler(dllWatcher_Changed);

        }



        void dllWatcher_Changed(object sender, FileSystemEventArgs e)

        {

            try

            {

                Console.WriteLine("file" + e.FullPath + "was updated at " + DateTime.Now.ToString());

            }

            catch (Exception ex)

            {

                Console.WriteLine("file" + e.FullPath + "can't be updated at " + DateTime.Now.ToString() + ex.Message);

            }

        }

    }

}

测试下:运行后,在DLL文件夹中丢一个123.txt,出现如下结果:

    1

发现一个问题,丢一个文件进去,OnChange事件触发了多次(这里是两次),一个文件也被解析执行了多次。

    目前这种情况还没有找到彻底解决的办法,而为了保证一次异动,changed事件只触发一次,只能采取一些不是办法的办法来避免。根据这些多次触发的事件是在短时间内完成的特点,这里采用一个键值对,键(文件名称)值(档次执行的时间点)对来记录一个文件异动的时间,当再次触发时,检查这个键值对,找到对应的文件,看它上次执行的时间,如果在设置的特定的时间内,则返回,取消本次执行。

using System;

using System.Collections.Generic;

using System.IO;



namespace fileSystemWatcherDemo

{

    /// <summary>

    /// FileSystemWatcher 组é件t应|用?Demo

    /// </summary>

    class fileSystemWatcherDemo

    {

        private FileSystemWatcher dllWatcher;



        //用于解决同一文件一次异动的多次事件触发问ê题a

        private Dictionary<string, DateTime> watcherChangedTimes = null;



        static void Main(string[] args)

        {

            Console.WriteLine("file Watcher Started  at " + DateTime.Now.ToString());



            fileSystemWatcherDemo watcher = new fileSystemWatcherDemo();

            watcher.beginWatcher();



            Console.Read();

        }



        private void beginWatcher()

        {

            watcherChangedTimes = new Dictionary<string, DateTime>();



            dllWatcher = new FileSystemWatcher();

            dllWatcher.Path = @"D:\ScheduledJob\DLL";

            dllWatcher.IncludeSubdirectories = false;

            dllWatcher.Filter = "*.*";

            dllWatcher.NotifyFilter = NotifyFilters.LastWrite;

            dllWatcher.EnableRaisingEvents = true;

            dllWatcher.Changed += new FileSystemEventHandler(dllWatcher_Changed);



        }



        void dllWatcher_Changed(object sender, FileSystemEventArgs e)

        {

            #region 60秒内同一个文件只处理一次
DateTime now = DateTime.Now; int reloadSeconds = 60; if (watcherChangedTimes.ContainsKey(e.FullPath)) { if (now.Subtract(watcherChangedTimes[e.FullPath]).TotalSeconds < reloadSeconds) { return; } else { watcherChangedTimes[e.FullPath] = now; } } else { watcherChangedTimes.Add(e.FullPath, now); } #endregion try { Console.WriteLine("file" + e.FullPath + "was updated at " + DateTime.Now.ToString()); } catch (Exception ex) { Console.WriteLine("file" + e.FullPath + "can't be updated at " + DateTime.Now.ToString() + ex.Message); } } } }

再丢一个文件1.jpg进去,运行结果如下:

2

你可能感兴趣的:(Watcher)