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

posted on 2011-02-13 11:33  easy2Dev  阅读(526)  评论(0编辑  收藏  举报

导航