简体   繁体   English

在C#中使用带有fileSystemWatcher的计时器

[英]Use timer with fileSystemWatcher in C#

The scenario is that I have a root folder to monitor any new folder (that contains files) and set a timer to zip each of them individually. 方案是我有一个根文件夹来监视任何新文件夹(包含文件)并设置一个计时器来单独压缩每个文件夹。 However, I can't tell if the file in the folder is the last file before calling the zip function, and therefore I want to reset a timer to that folder, whenever there is a new file created before zipping the folder. 但是,在调用zip函数之前,我无法判断文件夹中的文件是否是最后一个文件,因此,只要在压缩文件夹之前创建了新文件,我就想将计时器重置为该文件夹。

I using FileSystemWatcher to monitor both root folder and its sub-folders. 我使用FileSystemWatcher来监视根文件夹及其子文件夹。

  1. I'm not sure how to create another watcher to monitor the file creation, perhaps in the OnTimedEvent method. 我不知道如何创建另一个观察者来监视文件创建,也许是在OnTimedEvent方法中。
  2. I don't know how to reset the timer once detect a file of that folder. 一旦检测到该文件夹​​的文件,我不知道如何重置计时器。 What I think is also write the code in the OnTimedEvent to reset it. 我认为也是在OnTimedEvent中编写代码来重置它。

Below is part of my attempted code and the source code can be found here . 下面是我尝试过的代码的一部分,源代码可以在这里找到。 Any help will be highly appreciated. 任何帮助将受到高度赞赏。

    public class FileWatcher
    { 
     private FileSystemWatcher _watcherRoot;
     private Timer _timer;
     private readonly string _watchedPath;

    public FileWatcher(string path)
    {
        // _watcher = new FileSystemWatcher();
        _timer = new Timer();
        _watchedPath = path;


        InitWatcher();
    }

    public void InitWatcher()
    {
        _watcherRoot = new FileSystemWatcher();
        _watcherRoot.Path = _watchedPath;
        _watcherRoot.IncludeSubdirectories = true;
        _watcherRoot.EnableRaisingEvents = true;
        _watcherRoot.Created += new FileSystemEventHandler(OnCreated);

    }

    private void OnCreated(object sender, FileSystemEventArgs e)
    {

        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            string fullPath = e.FullPath;
            if (sender == _watcherRoot)
            {
                // If detect new folder, set the timer to 5 sec
                _timer.Interval = 5000;
                _timer.Elapsed += OnTimedEvent;
                _timer.AutoReset = true;
                _timer.Enabled = true;

                // a directory
                Console.WriteLine($"{fullPath.ToString()} created on {DateTime.Now}");
            }

        }
    }

    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        // Create a 2nd Watcher??
        // Reset the timer in here??
    }

Here you have a simple extension method to reset given timer. 这里有一个简单的扩展方法来重置给定的计时器。

  public static void Reset(this Timer timer)
    {
      timer.Stop();
      timer.Start();
    }

To get a timer object from inside of event you need to cast sender to System.Timers.Timer() or just use timer in static context. 要从事件内部获取计时器对象,您需要将sender System.Timers.Timer()System.Timers.Timer()或者只在静态上下文中使用计时器。

There's a very clever library called Reactive Extensions , originally written by Microsoft as "Rx" but now placed in a "System.Reactive" namespace. 有一个非常聪明的库Reactive Extensions ,最初由Microsoft编写为“Rx”,但现在放在“System.Reactive”命名空间中。 It allows you to write complex event-driven code very simply. 它允许您非常简单地编写复杂的事件驱动代码。

For example, in a scenario like the one you're describing, you could "react" to the FileSystemWatcher 's events and use a Reactive "Throttle", which means you would only get notified of an event after a period of time when that event had not occurred. 例如,在您正在描述的场景中,您可以对FileSystemWatcher的事件做出“反应”并使用Reactive“Throttle”,这意味着只有在一段时间之后才会收到事件的通知。事件没有发生。 You can also merge multiple different events together. 您还可以将多个不同的事件合并在一起。 Put these two features together, and subscribe your method to it. 将这两个功能放在一起,并订阅您的方法。

If that sounds like a possible solution, you may like to take a look at Intro to Rx , and here is a question relating to that approach to solving this problem, including about 4 ways of doing this in the various answers: Wrap a file watcher in reactive extensions (this is not a duplicate of that question because you're asking about Timers, and I'm suggesting you might want to use Reactive Extensions). 如果这听起来像是一个可能的解决方案,你可能想看看Rx的Intro ,这里有一个与解决这个问题的方法有关的问题,包括在各种答案中做到这一点的4种方法: 包装文件观察器在反应式扩展中 (这不是该问题的重复,因为你问的是Timers,我建议你可能想要使用Reactive Extensions)。

我使用lambda表达式来解决这个问题,将计时器和观察者“绑定”在一起,这就是我发现的类似于这篇文章的内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM