C # FileSystemWatcher События не запускаются - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь реализовать FileSystemWatcher. Однако мой обработчик событий OnChange никогда не вызывается. Предполагается, что наблюдатель отслеживает файл журнала, который обновляется другим потоком в процессе. Файл открывается с помощью new StreamWriter(File.Open("C:\\temp\\myLog.txt", FileMode.Create, FileAccess.Write, FileShare.Read)); Есть идеи?

public MyFormConstructor()
{
    InitializeComponent();

    this._fileSystemWatcher = new FileSystemWatcher();
    this._fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
    this._fileSystemWatcher.Path = "C:\\temp\\";
    this._fileSystemWatcher.Filter = "myLog.txt";
    this._fileSystemWatcher.Changed += this.OnLogChanged;
    this._fileSystemWatcher.Created += this.OnLogChanged;
    this._fileSystemWatcher.Deleted += this.OnLogChanged;
    this._fileSystemWatcher.Renamed += this.OnLogChanged;
    this._fileSystemWatcher.EnableRaisingEvents = true;
}

private void OnLogChanged(object source, FileSystemEventArgs e)
{
    switch (e.ChangeType) // <-- never gets here
    {
        case WatcherChangeTypes.Changed:
            this.UpdateLogView();
            break;
        case WatcherChangeTypes.Created:
        case WatcherChangeTypes.Deleted:
        case WatcherChangeTypes.Renamed:
        default:
            throw new NotImplementedException();
    }
}

1 Ответ

0 голосов
/ 25 октября 2019

Я получаю событие файловой системы при удалении StreamWriter, но не раньше.

Так что избавьтесь. В Приложении A приведены идеи, которые я не смог получить.

public class FlushingTextTraceListener : TextWriterTraceListener
{
    public FlushingTextTraceListener(string filePath)
    {
        FilePath = filePath;
    }
    public String FilePath { get; set; }

    public override void Write(string message)
    {
        using (var sw = new StreamWriter(File.Open(FilePath, FileMode.Create, 
            FileAccess.Write, FileShare.Read)))
        {
            sw.Write(message);
        }
    }

    public override void WriteLine(string message)
    {
        using (var sw = new StreamWriter(File.Open(FilePath, FileMode.Create, 
            FileAccess.Write, FileShare.Read)))
        {
            sw.WriteLine(message);
        }
    }
}

Использование:

_dbgTraceListener = new FlushingTextTraceListener("C:\\temp\\myLog.txt");
Debug.Listeners.Add(_dbgTraceListener);

Приложение A

Другие вещи, которые я пробовал, подробно описаны, потому что я, возможно, испортил одну или все из них. Для тестирования я поместил кнопку в окно WPF и в методе нажатия кнопки проследил строку текста:

Trace.WriteLine(DateTime.Now);

В этом обработчике событий после этой строки я попробовал несколько разных вещей. Конечно, вы не ищете метод-оболочку для Trace.WriteLine (), но я подумал, что если бы один из них работал, был бы какой-то способ использовать его чисто.

Это не вызывало событие файловой системы, но они не вызывали исключение:

Trace.Flush();

_dbgTraceListener.Flush();

_dbgOutputWriter.Flush();

Я пытался «дотронуться» до файла, установив время последнего доступа двумя способами, нополучено исключение (System.IO.IOException: «Процесс не может получить доступ к файлу« C: \ temp \ myLog.txt », поскольку он используется другим процессом.»)

new FileInfo("C:\\temp\\myLog.txt").LastWriteTime = DateTime.UtcNow;

File.SetLastWriteTimeUtc("C:\\temp\\myLog.txt", DateTime.UtcNow);

Я обнаружил, чтоЯ получил событие доступа, когда набрал type c:\temp\myLog.txt в cmd.exe, поэтому я попытался открыть файл только для чтения в C # и быстро его утилизировать. Я не пытался запустить процесс cmd.exe с type myLog.txt или type nul > myLog.txt, потому что это казалось гораздо более глупым решением, чем работавшее выше.

using (var f = File.Open("C:\\temp\\myLog.txt", FileMode.Open, 
                         FileAccess.Read, FileShare.Read))
    ;

И

using (var f = File.OpenRead("C:\\temp\\myLog.txt"))
    ;

Я получил то же исключение, что и выше, в обоих случаях. Для этого теста я создал _dbgOutputWriter с флагом FileShare.ReadWrite следующим образом:

_dbgOutputWriter = new StreamWriter(File.Open("C:\\temp\\myLog.txt", FileMode.Create, 
                                    FileAccess.Write, FileShare.ReadWrite));

FileShare.ReadWrite:

Разрешает последующее открытие файладля чтения или письма. Если этот флаг не указан, любой запрос на открытие файла для чтения или записи (этим процессом или другим процессом) не будет выполнен, пока файл не будет закрыт. Однако, даже если этот флаг указан, могут потребоваться дополнительные разрешения для доступа к файлу.

Выделить мое. Возможно, это просто означает, что пользователь должен иметь доступ к файлу для начала.

Я добавил NotifyFilters.LastAccess к NotifyFilter в FileSystemWatcher, но это не имело значения, что я заметил.

...