在没有FileSystemWatcher的情况下监视目录以创建新文件

Abb*_*bbi 7 .net .net-2.0

我必须创建一个Windows服务,它监视指定文件夹中的新文件并对其进行处理并将其移动到其他位置.

我开始使用FileSystemWatcher.我的老板不喜欢FileSystemWatcher并希望我使用Timer除了之外的任何其他机制来使用轮询FileSystemWatcher.

如何在不FileSystemWatcher使用.NET框架的情况下监控目录?

Mik*_*son 17

实际上,根据我多年来的经验,FileWatcher组件并非100%"稳定".将足够多的文件压入文件夹,您将丢失一些事件.如果监视文件共享,即使增加缓冲区大小,也尤其如此.

因此,出于所有实际原因,请使用FileWatcher和Timer扫描文件夹中的更改,以获得最佳解决方案.

如果你谷歌它,创建计时器代码的例子应该是丰富的.如果在计时器运行时跟踪最后一个DateTime,则检查每个文件的修改日期,并将其与日期进行比较.相当简单的逻辑.

计时器间隔取决于系统更改的紧急程度.但是检查每一分钟应该适用于许多场景.

  • 大多数`FileSystemWatcher`可靠性问题来自对其工作原理的误解.当磁盘写入排队时,不会引发`Changed`事件,而是在写入提交后才会引发.磁盘缓存后面的写入可以通过无限期地延迟它们来影响事件的及时性.报告的解决方案是通过`FlushFileBuffers`刷新缓存.我怀疑网络共享存在其他问题,这些问题会对可靠性产生负面影响. (9认同)
  • +1这是正确的解决方案:FileWatcher加上轮询作为备份来处理FileWatcher未命中的内容.-1每个认为FileWatcher可靠的人. (4认同)

Con*_*rix 6

使用@ Petoj的答案我已经包含了一个完整的Windows服务,每五分钟轮询一次新文件.它只限于一个线程轮询,占用处理时间并支持暂停和及时停止.它还支持在system.start上轻松附加debbugger

 public partial class Service : ServiceBase{


    List<string> fileList = new List<string>();

    System.Timers.Timer timer;


    public Service()
    {
        timer = new System.Timers.Timer();
        //When autoreset is True there are reentrancy problems.
        timer.AutoReset = false;

        timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
    }


    private void DoStuff(object sender, System.Timers.ElapsedEventArgs e)
    {
       LastChecked = DateTime.Now;

       string[] files = System.IO.Directory.GetFiles("c:\\", "*", System.IO.SearchOption.AllDirectories);

       foreach (string file in files)
       {
           if (!fileList.Contains(file))
           {
               fileList.Add(file);

               do_some_processing();
           }
       }


       TimeSpan ts = DateTime.Now.Subtract(LastChecked);
       TimeSpan MaxWaitTime = TimeSpan.FromMinutes(5);

       if (MaxWaitTime.Subtract(ts).CompareTo(TimeSpan.Zero) > -1)
           timer.Interval = MaxWaitTime.Subtract(ts).TotalMilliseconds;
       else
           timer.Interval = 1;

       timer.Start();
    }

    protected override void OnPause()
    {
        base.OnPause();
        this.timer.Stop();
    }

    protected override void OnContinue()
    {
        base.OnContinue();
        this.timer.Interval = 1;
        this.timer.Start();
    }

    protected override void OnStop()
    {
        base.OnStop();
        this.timer.Stop();
    }

    protected override void OnStart(string[] args)
    {
       foreach (string arg in args)
       {
           if (arg == "DEBUG_SERVICE")
                   DebugMode();

       }

        #if DEBUG
            DebugMode();
        #endif

        timer.Interval = 1;
        timer.Start();
   }

   private static void DebugMode()
   {
       Debugger.Break();
   }

 }
Run Code Online (Sandbox Code Playgroud)

  • 代码缺少类宽的`LastChecked`变量声明. (3认同)