我最近一直在开发一个 RTF 编辑器,它只是一个简单的 UserControl
,它有一个 RichTextBox
和几个事件,比如 PreviewTextInput
和PreviewMouseUp
。
不过我注意到有些事情有点烦人。
每当调整 UI 大小时,RichTextBox
的性能绝对糟糕,并且 RichTextBox
有大量文本导致其环绕算法触发。
这给应用程序一种非常草率的感觉,就好像它没有得到很好的优化(即使它不是)。
起初我注意到在选择文本时性能受到影响,所以我没有使用 SelectionChanged
事件,而是决定使用 PreviewMouseUp
事件然后获取选择。
然后经过进一步测试,我发现调整大小也造成了巨大的负载。 我说的是运行频率为 3.8GHz 的四核 CPU 的负载范围在 5% -> 30% 之间!
为了进一步测试,我决定注释掉我的 RichTextBox
并只包含一个没有定义属性的新 RichTextBox
<RichTextBox/>
将其插入到一个窗口中,填充文本,然后调整窗口大小以使环绕算法再次执行相同操作,使用率高达 30%!
我试图研究这个问题,大多数人最终建议将 PageWidth
设置为高值以防止换行:
richTextBox1.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
richTextBox1.Document.PageWidth = 1000;
这是我不想要的,因为我之前编写的编辑器版本是用 WinForms 制作的,可以毫不费力地进行包装,而且我也希望在新的 WPF 版本中使用它。
有没有其他人遇到过这个问题? 如果是,能否请您指出正确的方向以消除硬件上的巨大压力?
我有点难过,因为我喜欢 WPF,但我确实发现一个或另一个对象与 WinForms 对象相比确实没有优化和/或不实用,RichTextBox
似乎是另一种情况:(
对于大量的文本,我深表歉意,但我真的很想把它整齐地记录下来,以防其他可怜的人遇到这个问题,并让你们看看我到目前为止所做的尝试。
最佳答案
解决此问题的一种方法可能是在调整窗口大小时切换到“无环绕”模式,但当用户完成调整大小时切换回正常模式。然后包装算法将在最后只执行一次,用户应该仍然对您的应用程序有流畅的感觉。示例代码:
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
this.SizeChanged += OnSizeChanged;
}
private Timer _timer;
private void OnSizeChanged(object sender, SizeChangedEventArgs e) {
// user started resizing - set large page width
textBox.Document.PageWidth = 1000;
// if we already setup timer - stop it and start all over
if (_timer != null) {
_timer.Dispose();
_timer = null;
}
_timer = new Timer(_ => {
// this code will run 100ms after user _stopped_ resizing
Dispatcher.Invoke(() =>
{
// reset page width back to allow wrapping algorithm to execute
textBox.Document.PageWidth = double.NaN;
});
}, null, 100, Timeout.Infinite);
}
}
关于c# - RichTextBox - UI 调整大小导致巨大的 CPU 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39849599/