【问题标题】:Large strings added to a text box freezing my program将大字符串添加到冻结我的程序的文本框中
【发布时间】:2020-03-20 13:13:33
【问题描述】:

此程序将文件打开到文本框中。它适用于大小为 4KB 的小文件,但我在处理 200KB 的文件时遇到了问题。理想情况下,我希望能够打开任何大小的文件,但是将大文件打开到文本框中会冻结程序。我做错了什么?

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                StreamReader sr = new StreamReader(openFileDialog1.FileName);
                Text = openFileDialog1.FileName + " - " + "Fixprt";
                textBox1.Text = String.Empty;

                while (!sr.EndOfStream)
                {
                    textBox1.Text += sr.ReadLine() + Environment.NewLine;
                }
                sr.Close();
            }
            openFileDialog1.Dispose();
        }

【问题讨论】:

  • 为什么不一次全部加载呢?例如:textbox1.Text = File.ReadAllText(openFileDialog1.FileName); 或者你可以读取所有行,string[] lines = System.IO.File.ReadAllLines(openFileDialog1.FileName); 然后使用lines 做你想做的事。
  • 无论文件大小如何都会冻结程序
  • 在循环中连接字符串是个坏主意,至少你应该使用 StringBuilder。还有为什么不让它异步。
  • @cd5ssmffan 这是标准行为,当您在 UI 上加载这些数据时会发生什么?其中一个问题是,实际的 Text 属性会在幕后进行检查以确定新值是否与当前值不同......当这样做时,可能数千次,它是一个问题;做一次,不要冲洗并重复。

标签: c# memory textbox streamreader


【解决方案1】:
  1. 逐行读取文件会产生不必要的开销。一次读取所有文件会更好。

  2. 考虑使用异步/等待。这将为您带来更具响应性的界面。

所以我建议下一个解决方案:

    private async void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            StreamReader sr = new StreamReader(openFileDialog1.FileName);
            Text = openFileDialog1.FileName + " - " + "Fixprt";

            textBox1.Text = await sr.ReadToEndAsync();

            sr.Close();
        }
        openFileDialog1.Dispose();
    }

编辑

正如 cmets 中所讨论的,此解决方案无法正确处理 unix 样式的换行符。对于这种情况,它可以是其他决定:

   private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            StreamReader sr = new StreamReader(openFileDialog1.FileName);
            Text = openFileDialog1.FileName + " - " + "Fixprt";

            var sb = new StringBuilder();
            while (!sr.EndOfStream)
            {
                sb.AppendLine(sr.ReadLine());
            }
            textBox1.Text = sb.ToString();

            sr.Close();
        }
        openFileDialog1.Dispose();
    }

现在我们使用StringBuilder,专为快速处理字符串数据而设计。

【讨论】:

  • 谢谢,这解决了问题。但是,文本文件中的换行符被忽略
  • @Çöđěxěŕ,是的,使用视觉元素会导致额外的计时,但它可能是 TS 需要解决的任务的一部分 - 一些文本编辑器等。
  • @cd5ssmffan,这很奇怪 - 我在几个文件上测试了它,所有的中断都没有改变。
  • 因为您在上面的代码中添加了中断,所以这个答案没有......再次阅读我的 cmets,这就是他们在那里的原因。
  • @Çöđěxěŕ 不,我不是
猜你喜欢
  • 2011-04-02
  • 2019-12-17
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 2015-04-05
  • 1970-01-01
  • 2016-09-04
相关资源
最近更新 更多