【问题标题】:streamReader inside OnChanged fires twice?OnChanged 内的 streamReader 触发两次?
【发布时间】:2016-03-27 17:41:14
【问题描述】:

我有一个监视特定文件的小应用程序,每当它发生变化时,我的应用程序都应该执行循环中的操作,但有些东西会多次触发该函数!这是我的代码

private void OnChanged(object source, FileSystemEventArgs e)
    {
        if (e.FullPath == @"C:\test.txt")
        {
            string textFilePath = @"C:\test.txt";

            try
            {
                using (var streamReader = File.OpenText(textFilePath))
                {
                    var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    foreach (var line in lines)
                    {
                        //actions here
                    }
                }
            }
            catch (Exception)
            {
            }
        }
    }

所以我猜测当streamreader 执行File.OpenText 以某种方式再次触发该函数时?有什么想法吗?

【问题讨论】:

  • 我只是把它留空以进行调试,我保证这不是我的最终代码:)

标签: c# onchange streamreader filesystemwatcher opentext


【解决方案1】:

来自MSDN

更改大小、系统属性、上次写入时间、上次访问时间、...

时会引发 Changed 事件

所以是的,打开(实际上:关闭)文件将再次引发 Changed 事件。

您可以使用NotifyFilter 来限制您的观察者触发的操作。

【讨论】:

  • 谢谢!我使用了NotifyFilter.Size ,它起作用了,我现在唯一的问题是,如果文件的更新大小相同,它就不起作用了!例如:文件是:test1,更新是:test2 它不会改变大小!如果我输入watch.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite; ,它将被解雇两次:/
  • 没关系,我做了一些有帮助的事情。我会用解决方案更新我的问题
  • 好的,谢谢您.. 我将解决方案发布为答案
【解决方案2】:

解决方案 所以我做了一件小事来控制问题,我添加了一个计数器并始终检查它是否不是第一次,跳过并将其重新分配为 0。

private int fireCounter = 0;

    private void OnChanged(object source, FileSystemEventArgs e)
    {
        fireCounter++;

        if (fireCounter == 1)
        {
            delete();

            if (e.FullPath == @"C:\test.txt")
            {
                Thread.Sleep(2000);
                //I added Sleep for two seconds because without it sometimes it wont work

                string textFilePath = @"C:\test.txt";
                try
                {
                    using (var streamReader = File.OpenText(textFilePath))
                    {
                        var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        foreach (var line in lines)
                        {
                            //Actions Here
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
        }
        else
        {
            fireCounter = 0;
        }
    }

【讨论】:

  • 是的,在你回答我之前我已经有了它,正如我在之前的评论中所说,NotifyFilter.Size 并没有真正帮助,我已经有了NotifyFilter.LastWrite,它在文件时首先触发两次真的更新了,第二次当streamReader = File.OpenText(textFilePath) 所以唯一的办法就是控制第二次触发
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
相关资源
最近更新 更多