C#FileWatcher文件读取后不可用

C#FileWatcher文件读取后不可用,c#,file-io,C#,File Io,我刚从C#开始,我尝试创建一个FileWatcher,如果文件发生更改,它应该打印文件的内容: { public static void watch() { FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = "Path"; watcher.NotifyFilter = NotifyFilters.LastWrite; watcher.Filter

我刚从C#开始,我尝试创建一个FileWatcher,如果文件发生更改,它应该打印文件的内容:

{
    public static void watch()
    {
      FileSystemWatcher watcher = new FileSystemWatcher();
      watcher.Path = "Path";
      watcher.NotifyFilter = NotifyFilters.LastWrite;
      watcher.Filter = "Filter";
      watcher.Changed += new FileSystemEventHandler(OnChanged);
      watcher.EnableRaisingEvents = true;
    }
    public static void OnChanged(object source, FileSystemEventArgs e)
    {
        using (TextReader r = File.OpenText("Path")) {
         while ((s = r.ReadLine()) != null) {
              Console.WriteLine(s);
         }
         r.Close();
      }
    }
    static void Main()
    {
        watch();
    }
}
到目前为止,FileWatcher工作正常,但如果我尝试打印内容,它会工作一次,无论我等待多长时间,程序都会停止第二次更改。 据我所知,“using”语句应该释放文件。close命令根本不会更改任何内容

该文件是一个非常小的文本文件,应该不会有问题


是否仍有强制程序释放文件的方法?

要做的第一件事是调试并验证您的方法
OnChanged
是否只被调用一次,或者在以下编辑受监控文件时也被调用一次,那么您已经知道问题是与监视程序的生存期/范围有关还是与其他地方有关


这是一个控制台应用程序吗?在调用main中的watch方法后,它是关闭还是保持打开状态?

您需要处理FileSystemWatcher

public static void OnChanged(object source, FileSystemEventArgs e)
    {
        using (TextReader r = File.OpenText("Path")) {
         while ((s = r.ReadLine()) != null) {
              Console.WriteLine(s);
         }
         r.Close();
      }
      File((FileSystemWatcher)sender).Dispose();
    }

我认为,在您的情况下,应该使用
watcher.WaitForChanged(WatcherChangeTypes.All)
,而不是
watcher.EnableRaisingEvents=true
,让您的程序无限期地等待更改

顺便说一句,语句
r.Close()
是多余的,因为您已经通过
using
隐式调用了
Dispose()
,这反过来又调用了
Close()

编辑:更具体地说:
WaitForChanged
当然,只需等待一个更改,然后返回,因此如果要等待更多更改,可以使用循环。请注意,如果以这种方式使用,则不需要事件处理程序

while(true)
{
    watcher.WaitForChanged(WaitForChanged.All);
    // Do stuff with the changed file here, no event handler needed
    using(var sr = new StreamReader(filePath))
    {
        // ...
    }
}

以下代码可以正常工作:

using System;
using System.IO;

namespace FileReadTest
{
    internal class Program
    {
        public static FileSystemWatcher watch()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = "d:\\";
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Filter = "test.txt";
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
            return watcher;

        }
        public static void OnChanged(object source, FileSystemEventArgs e)
        {
            string s;

            using (StreamReader r = new StreamReader(File.Open("d:\\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                while ((s = r.ReadLine()) != null)
                {
                    Console.WriteLine(s);
                }
            }
        }

        static void Main()
        {
            var watcher = watch();
            Console.ReadKey();
            watcher.Dispose();
        }
    }
}

请注意,我已经更改了文件读取例程,以避免在其他程序打开文件时出现一些读取问题<代码>FileSystemWatcher也不会超出范围,也不会被意外处置

可能正在收集您的
观察者
对象。尝试将其升级为字段。您能告诉我们您的程序引发的异常吗?不是答案(问题在别处),而是建议:将
OnChanged()
更改为
Console.WriteLine(File.ReadAllText(“Path”)sasha_gud的答案工作正常,问题是文本阅读器。使用StreamReader解决问题是可行的。谢谢大家的建议!我会尝试,但正如我已经写的,没有文本阅读器一切都很好,所以我猜是阅读器没有正确地释放资源。该程序是一个控制台应用程序,它一直监视一个文件,每次更改后我都尝试读取它。看起来很好,我正在寻找这个。我明天试试!我尝试了你的建议(在我现在正在工作的代码中),并且为了r.Close你明显的正确。但我试着按照你的建议更换了Watcher,但它只是打印了第一次更改。因此,也许
watcher.EnableRaisingEvents=true)
在我的例子中工作得更好。是的,好吧,这就是方法
WaitForChanged
所做的-它等待一个更改,然后返回。要继续等待下一个更改,必须执行循环。见编辑。呃。。。嗯<代码>文件((FileSystemWatcher)发件人).Dispose()。。。什么