C#FileSystemWatcher事件未触发

问题描述 投票:0回答:1

我正在尝试实现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();
    }
}
c# event-handling filesystemwatcher
1个回答
0
投票

我在处理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窗口上放置了一个按钮,并在该按钮的click方法中跟踪了一行文本:

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);

[我在cmd.exe中键入type c:\temp\myLog.txt时发现访问事件,因此我尝试在C#中以只读方式打开文件并立即将其处理:

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

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

在两种情况下,我都有与上述相同的例外。对于此测试,我使用FileShare.ReadWrite标志创建了_dbgOutputWriter,如下所示:

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

FileShare.ReadWrite

允许随后打开文件进行读取或写入。如果未指定此标志,则打开文件以进行读取或写入的任何请求(通过此过程或其他过程)都将失败,直到关闭文件为止。但是,即使指定了此标志,可能仍需要访问文件的附加权限。

强调我的。也许这只是意味着用户必须有权访问文件。

© www.soinside.com 2019 - 2024. All rights reserved.