【问题标题】:C# - How to Optimize SystemFileWatcherC# - 如何优化 SystemFileWatcher
【发布时间】:2026-01-04 23:05:02
【问题描述】:

我有一个允许用户查看实时日志文件的 SystemFileWatcher。其中一些日志文件可能会变得非常大,有时会通过 VPN 读取,从而进一步减慢进程。有没有办法优化我的更改事件?我已经得到它,它可以工作,并显示信息,并且不会重复或显示过去的事件,但我在表单上的按钮也被锁定。所以我的第一个问题是如何进一步优化我的代码?我的第二个问题是如何与我的表单交互?

private void fileWatcher_Changed(object sender, FileSystemEventArgs e)
    {
        fileWatcher.EnableRaisingEvents = false;
        var fs = new FileStream(GlobalVar.GlobalString, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using (var sr = new StreamReader(fs))
        {
            var s = "";
            int copyGood = 0;
            bool result = false;
            bool copyModeOn = false;
            var newDateTime = new DateTime();
            List<string> list = new List<string>();
            if (GlobalVar.GlobalLineCount > 0)
            {
                for (var i = 0; i < GlobalVar.GlobalLineCount; i++)
                {
                    sr.ReadLine();
                }
                while ((s = sr.ReadLine()) != null)
                {
                    list.Add(s);
                }
            }
            else
            {
                while ((s = sr.ReadLine()) != null)
                {
                    list.Add(s);
                }
            }
            GlobalVar.GlobalLineCount = list.Count();
            list.Reverse();
            var list2 = list.Take(50).Reverse().ToList();

              foreach (string s1 in list2)
              {
                    if (s1.Length > 23)
                    {
                        var lineTime = s1.Substring(0, 23);
                        result = DateTime.TryParse(lineTime, out newDateTime);
                    }
                    if (newDateTime != null && result)
                    {
                        DateTime lineTime = Convert.ToDateTime(newDateTime.ToString(@"HH:mm:ss.fff"));
                        DateTime dt = Convert.ToDateTime(GlobalVar.GlobalDateTimeString);
                        DateTime globalTimeSet = Convert.ToDateTime(dt.ToString(@"HH:mm:ss.fff"));
                        copyGood = DateTime.Compare(globalTimeSet, lineTime);
                    }
                    if (result && copyGood < 0)
                    {
                        if (richTextBox1.Lines.Length > 0)
                        {
                            foreach (string line in richTextBox1.Lines)
                            {
                                if (line == s1)
                                {
                                    copyModeOn = false;
                                    break;
                                }
                                copyModeOn = true;
                            }
                        }
                        else
                        {
                            copyModeOn = true;
                        }
                        if (copyModeOn)
                        {
                            richTextBox1.AppendText(Environment.NewLine + s1 );
                            richTextBox1.Focus();
                            richTextBox1.Select(richTextBox1.TextLength, 0);
                            richTextBox1.ScrollToCaret();
                        }
                    }
                }
        }
        fileWatcher.EnableRaisingEvents = true;
    }`

您能提供的任何帮助将不胜感激!

【问题讨论】:

  • 如果您的代码工作正常并且您只是想改进它,这个问题可能更适合 CodeReview@StackExchange。作为第一个提示:如果您不希望您的操作阻塞您的 UI 线程,请尝试使其异步(例如,使用 async/awaitTasks 或 BackgroundWorker,如果您是 C#4 之前的用户)对于性能本身:瓶颈很可能是 I/O 和网络系统,你很难通过代码来改善。
  • 这听起来很像不是FileSystemWatcher 那是你的瓶颈(坦率地说,即使是通过 VPN,这会让我对 单个文件感到惊讶),而是代码您用来读取更改的速度很慢。那么,这与»优化« FileSystemWatcher 无关。您可以尝试通过BackgroundWorker 将更改卸载到后台线程,以便 UI 保持响应。请注意,您需要再次从 UI 线程更改您的 GUI。

标签: c# winforms optimization


【解决方案1】:

不是真的。最大的收获是两者之间没有远程网络连接 - 这意味着将大部分处理转移到应用程序服务器,并且只通过网络发送所需的线路。

你应该做的不是阅读整个文件。显然,日志文件条目的大小是有限的。没有必要一遍又一遍地从结尾开始;)您可以假设每行的最大大小(比如说 512 字节),仅此一项就可以减少大文件的大量读取。或者您实际上可以记住上次读取的位置。

【讨论】: