【问题标题】:Frequently writing to WPF Textbox crashes application频繁写入 WPF 文本框会导致应用程序崩溃
【发布时间】:2019-12-11 00:25:19
【问题描述】:

我有一个包含多个选项卡的应用程序。这些选项卡之一是充当输出控制台的“报告”选项卡。当我第一次运行应用程序时,我读取了一个文件并将大约 2000 行写入文本框。当不是“报告”选项卡的选项卡处于活动状态时,这可以正常工作。

但是,如果我正在查看“报告”选项卡(带有文本框),而它正在写入大量数据,应用程序会写入一两行数据然后不会响应。整个应用程序崩溃。

我用来更新的代码很简单:

string timestamp = DateTime.Now.ToString("H:mm:ss");
string output = this.textbox_report_output.Text;
output += timestamp + ": " + message + "\n";
this.textbox_report_output.Text = output;
this.textbox_report_output.ScrollToEnd();

当 WPF 的文本框承受这种压力时,我的表现非常糟糕。有什么我可以做的吗?

【问题讨论】:

  • 当你知道你要写大量的新行时,为什么不创建一个批量更新方法,在一个单独的线程上构建内存中的所有新行,然后将它们推送到一次真正的文本框?
  • 作为输出控制台是什么意思?所以你在整个代码块上循环多次?
  • 应用崩溃时抛出什么异常?我建议查看AppendText 方法。

标签: c# .net wpf textbox


【解决方案1】:

当 WPF 的文本框承受这种压力时,我的表现非常糟糕。有什么我可以做的吗?

是的,您可以正确编写 WPF 而不是假装它是 Windows 窗体。

在 WPF 中,我们使用数据绑定来更新 UI 而不是程序代码。我建议您仔细阅读 MSDN 上的 Data Binding Overview 页面以帮助您入门,但它基本上是这样的:

创建一个string 属性并实现INotifyPropertyChanged interface

public string Text { get; set; } // Implement the INotifyPropertyChanged interface

数据绑定到TextBox.Text属性:

<TextBox Text="{Binding Text}" />

设置值:

Text = "Some value";

使用Dispatcher 在您仍在执行其他代码时运行 UI 更新:

Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate { Text = "Some value"; });

【讨论】:

  • 虽然这总体上是一个很好的建议 (MVVM),但我怀疑它能否解决 OP 的性能问题。事实上,我认为 WinForms 也会有同样的问题,因为文本框根本不是为处理大量文本而设计的。更好的选择是使用为此目的设计的控件。
  • 实际上使用 String.Format 而不是 + 应该也有助于提高性能,但可能还不够
  • @LucasTrzesniewski 我不同意。这不是最终数量问题。 Op 声明它在更新期间该选项卡不活动时有效。他在 UI 中充斥着个人更新。
  • @Blam 好吧,你是对的,看起来我误解了那部分。但是我仍然认为使用像 AvalonEdit 这样的控件是处理大量文本的更好选择。
【解决方案2】:

显然,除了我要说的内容之外,还有一些问题,但由于您使用的是 WPF,因此有一种 比您正在使用的更新 UI 更好的方法。您可以让 WPF 绑定系统负责更新 UI 的后勤工作,而不是像您正在做的那样推送更新。

这样,更新不会淹没 UI 线程。为此,请创建一个 DependencyProperty(或实现 INotifyProperty 已更改),然后将文本框绑定到该属性。

也就是说,如果应用程序崩溃,您可能做错了什么。也许您正在泄漏内存并获得 OutOfMemoryException?!或者可能是一些线程问题?!

【讨论】:

    【解决方案3】:

    我同意其他两个回答,即数据绑定是 wpf 文本框输入和输出的最佳选择。但是,在某些情况下,您并没有那么奢侈,特别是当您需要的数据位于视图和您正在访问的控件是通过远程处理和格式化 UI 输出时很重要。

    如果您在 OnTextChanged 事件中设置 Textbox.Text 字段(在日文或中文并且您的输入是全角的),那么它很有可能会导致您的系统崩溃。尝试捕获 LostFocus 事件,然后在那里进行更正。然后,我们可以安全地设置 Textbox.Text 字段中的值。此外,您可以拦截 KeyDown 事件并删除除小数点以外的非数字键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多