2016-10-04 3 views
10

Я недавно разрабатывал RTF-редактор, который является простым UserControl, который имеет RichTextBox с парочкой таких событий, как PreviewTextInput и PreviewMouseUp.RichTextBox - UI Изменение размера вызывает огромную нагрузку на CPU

Я заметил что-то слегка раздражающее. Производительность RichTextBox абсолютно ужасна всякий раз, когда пользовательский интерфейс изменяется, и RichTextBox имеет много текста, чтобы вызвать его Алгоритм Обертывания.

Это дает Приложению действительно неряшливое чувство, как будто оно плохо оптимизировано (хотя это и не так).

Сначала я заметил это ударное действие при выборе текста, поэтому вместо использования события SelectionChanged я решил использовать событие PreviewMouseUp, а затем выбрать Selection.

Затем после дополнительных испытаний выяснилось, что изменение размера также вызвало огромные нагрузки. И я говорю о нагрузках от 5% до 30% с четырехъядерным процессором, работающим на частоте 3,8 ГГц!

Для дальнейшей проверки его, я решил прокомментировать мою RichTextBox и включать только новую RichTextBox без каких-либо определенной собственности

<RichTextBox/> 

Подставив это в окно, заполняя с текстом, а затем изменить размер окна, чтобы потому что Алгоритм Обертывания сделал то же самое снова, до 30% использования!

Я пытался исследовать по этому вопросу, и большинство людей в конечном итоге рекомендовать установки PageWidth до высоких значений для того, чтобы предотвратить Обтекание:

richTextBox1.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible; 
richTextBox1.Document.PageWidth = 1000; 

Что я не хочу, так как в предыдущей версии редактора Я написал, был сделан с WinForms и мог сделать Wrapping без усилий, и я также хочу его в новой версии WPF.

Неужели кто-нибудь еще сталкивался с этой проблемой? Если да, не могли бы вы указать мне в правильном направлении, чтобы устранить эту огромную нагрузку на оборудование?

Мне немного грустно, потому что я люблю WPF, но я нашел тот или иной объект, который действительно неоптимизирован и/или не практичен по сравнению с копией WinForms, RichTextBox, по-видимому, является еще одним из этих случаев :(

Извините за огромное количество текста, но я действительно хотел, чтобы документировать это аккуратно в случае какой-либо другой бедняга сталкивается с этим вопросом и для вас, ребят, чтобы увидеть то, что я пытался до сих пор.

ответ

7

One способ преодоления этой проблемы может заключаться в том, чтобы переключиться в режим «без обертки» при изменении размера окна, но когда пользователь закончил с изменением размера - вернитесь в нормальный режим. Затем алгоритм обертки будет выполняться только один раз в конце, а u sers все равно должны иметь гладкое представление о вашем приложении. Образец кода:

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); 
    } 
} 
+0

Забавно, как я не думал о том, что я выбрал выбор Resize Call, я думаю, я слишком устал. В вашем коде есть ошибка, в которой вы пытаетесь вызывать btw, следующие исправления: Dispatcher.Invoke (новое действие (() => {})); –

+0

Кстати, использование таймеров в этой ситуации является рискованным, потому что в зависимости от производительности ПК событие может или не может по-прежнему изменять размер, в моем случае мне пришлось использовать 300 мс для более или менее работы, но он определенно указал мне на правильное направление, я собираюсь изменить его, чтобы соответствовать моей необходимости, в конечном итоге избавиться от таймеров. Благодарю. –

+0

Если вы также заинтересованы в том, чтобы знать, как это работает, это помогло мне снизить накладные расходы на 50%, теперь это при использовании 15% при изменении размера, если много текста внутри, IMO RichTextBox - это огромный беспорядок в терминах производительности, так как кажется, что алгоритм Wrap не является единственным фактором, вызывающим эти проблемы, в любом случае, еще раз спасибо за то, что указал мне в правильном направлении;) –

Смежные вопросы