使用文件系统监视程序的Lambda表达式

时间:2018-10-30 21:21:04

标签: c# .net lambda delegates

在我的一生中,我无法弄清楚以下代码中这两个参数的来源。我已经在Visual Studio中对其进行了编译,并且可以正常工作,但是当您使用lambda表达式将匿名方法添加到FileSystemWatcher的委托中时,这些方法如何接收到这两个参数?他们来自哪里?当发生.Changed或.OnChanged事件时,FileSystemWatcher是否返回带有两个参数的数组?如果是这样,我将无法找到解释该问题的文档。这是代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDirectoryWatcher
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** The File Watcher App *****\n");

            // Establish the path to the directory to watch.
            FileSystemWatcher watcher = new FileSystemWatcher();
            try
            {
                watcher.Path = @"C:\MyFolder";
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("Press Enter to continue...");
                Console.ReadLine();
                return;
            }
            // Set up the things to be on the lookout for.
            watcher.NotifyFilter = NotifyFilters.LastAccess
              | NotifyFilters.LastWrite
              | NotifyFilters.FileName
              | NotifyFilters.DirectoryName;

            // Only watch text files.
            watcher.Filter = "*.txt";

            // Specify what is done when a file is changed, created, or deleted.
            watcher.Changed += (s, e) =>
            {
                Console.WriteLine("File: {0} {1}!", e.FullPath, e.ChangeType);
            };

            watcher.Created += (s, e) =>
            {
                Console.WriteLine("File: {0} {1}!", e.FullPath, e.ChangeType);
            };

            watcher.Deleted += (s, e) =>
            {
                Console.WriteLine("File: {0} {1}!", e.FullPath, e.ChangeType);
            };

            watcher.Renamed += (s, e) =>
            {
                // Specify what is done when a file is renamed.
                Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
            };

            // Begin watching the directory.
            watcher.EnableRaisingEvents = true;

            // Wait for the user to quit the program.
            Console.WriteLine(@"Press 'q' to quit app.");
            while (Console.Read() != 'q') ;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

只需选择一个事件...

watcher.Changed += OnChanged;
private void OnChanged(object sender, FileSystemEventArgs e){
  // Handle event
}

实际上,每次执行+ =时,您实际上就是将一个委托添加到Changed事件的调用列表中。在这种情况下,委托定义一个签名,该签名需要两个类型为object和FileSystemEventArgs的参数。

您可以使用lambdas来简化此操作: watcher.Changed + =(sender,args)=> {};

您需要查看事件的文档来确定签名(或使用类似Visual Studio的IDE): https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.changed

当文件系统监视程序需要调用事件(以通知消费者发生了什么事)时,它将调用事件调用列表中的所有委托,并传递发送者和FileSystemEventArgs。

答案 1 :(得分:0)

让我知道我是否不理解这个问题。所以watcher.Changed正在使用委托。因此,您要传递一个代码块,以便他们在该点上执行特定操作时执行。您只是将它们传递给代码以运行。

这是一个更简单的示例。

static void Main(string[] args)
    {
        DisplayString();
        Console.ReadLine();       
    }

    public static void DisplayString()
    {
        RunAction( (textToDisplay) =>
        {
            Console.Write(textToDisplay);
        });
    }
    private static void RunAction(Action<string> action)
    {
        action("This Is A Test");
    }

因此,在Action<string>;中,这是说我的代表正在等待一个字符串。传入这里

action("This Is A Test");

所以在您的示例中,代码是

  

公共委托void FileSystemEventHandler(object sender,FileSystemEventArgs e);

这意味着代码将通过(s,e)使用的两个对象传递给您

因此watcher.Changed被声明

  

Blockquote

公共事件FileSystemEventHandler已更改;

相关问题