Лямбда-выражения с наблюдателем файловой системы - PullRequest
0 голосов
/ 31 октября 2018

Я не могу понять, откуда взялись два аргумента в следующем коде. Я скомпилировал его в Visual Studio, и он работает, но когда вы используете лямбда-выражения для добавления анонимных методов в делегаты для FileSystemWatcher, как эти методы получают эти два аргумента? Откуда они? Возвращает ли FileSystemWatcher массив с двумя аргументами при возникновении событий .Changed или .OnChanged? Если так, я не смог найти документацию, которая объясняет это. Вот код:

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 голосов
/ 31 октября 2018

Просто чтобы выбрать одно из событий ...

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

Вы фактически добавляете делегата в список вызовов Измененного события каждый раз, когда делаете + =. В этом случае делегат определяет сигнатуру, которая требует два параметра типа object и FileSystemEventArgs.

Вы можете сократить это, используя лямбды: watcher.Changed + = (отправитель, аргументы) => {};

Вам нужно обратиться к документации по событию, чтобы определить сигнатуру (или использовать IDE, например Visual Studio): https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.changed

Когда наблюдателю файловой системы нужно вызвать событие (чтобы сообщить потребителям, что что-то произошло), он вызовет всех делегатов в списке вызовов событий, передавая отправителю и FileSystemEventArgs.

0 голосов
/ 31 октября 2018

Дайте мне знать, если я не понимаю вопроса. Поэтому 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 (отправитель объекта, FileSystemEventArgs e);

Это означает, что код передает вам те два объекта, которые вы используете через (s, e)

Итак, наблюдатель. Изменено объявлено

Blockquote

публичное событие FileSystemEventHandler Изменено;

...