Сокращение времени в C # Forms Control.set_Text (string) функция - PullRequest
3 голосов
/ 26 апреля 2010

Надеясь на быстрый ответ (который, кажется, очень хорош) ...

Я только что провел анализ производительности с VS2010 в своем приложении, и оказалось, что я трачу около 20% своего времени на функцию Control.set_Text(string), так как я обновляю ярлыки в довольно многих местах моего приложение.

В окне есть объект таймера (Таймер форм, а не Таймер потоков), который имеет обратный вызов timer1_Tick, который обновляет одну метку каждый тик (чтобы дать эффект секундомера) и обновляет около 15 меток один раз каждый второй.

У кого-нибудь есть быстрые предложения о том, как сократить количество времени, затрачиваемое на обновление текста в форме, кроме увеличения интервала обновления? Есть ли другие структуры или функции, которые я должен использовать?

Ответы [ 2 ]

6 голосов
/ 26 апреля 2010

Я сам столкнулся с этой проблемой и в итоге создал свой собственный простой элемент управления Label.

.Net Label control - удивительно сложный зверь, поэтому он медленнее, чем хотелось бы.

Вы можете создать класс, который наследует Control, вызвать SetStyle в конструкторе, чтобы сделать его буферизованным и нарисованным пользователем, затем переопределить метод OnPaint для вызова e.Graphics.DrawString и нарисовать Text свойство.
Наконец, переопределите Text или TextChanged и позвоните Invalidate.

Пока вам не нужен AutoSize, это будет значительно быстрее, чем стандартный элемент управления Label.

Вот моя реализация: (В настоящее время используется в производстве)

///<summary>A simple but extremely fast control.</summary>
///<remarks>Believe it or not, a regular label isn't fast enough, even double-buffered.</remarks>
class FastLabel : Control {
    public FastLabel() {
        SetStyle(ControlStyles.AllPaintingInWmPaint
               | ControlStyles.CacheText
               | ControlStyles.OptimizedDoubleBuffer
               | ControlStyles.ResizeRedraw
               | ControlStyles.UserPaint, true);
    }
    protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); Invalidate(); }
    protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); Invalidate(); }

    static readonly StringFormat format = new StringFormat {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Center
    };
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.DrawString(Text, Font, SystemBrushes.ControlText, ClientRectangle, format);
    }
}

Если вы не хотите центрироваться, вы можете избавиться или изменить StringFormat.

2 голосов
/ 26 апреля 2010

Что ж, присвоение свойства Text занимает около 0,6 наносекунд, отдача или взятие. Это побочные эффекты, которые стоят дорого. Возможно, у вас включено свойство AutoSize для меток. Поэтому необходимо создать дескриптор шрифта, визуализировать текст во временном контексте устройства, измерить результирующую строку, учитывая побочные эффекты из-за подсказки TrueType, которая искусственно растягивает форму буквы, так что она совпадает с пикселем на мониторе, а также корректировка измененных метрик ABC, чтобы заставить ClearType работать. Затем скажите родному элементу управления Windows, что ему нужно изменить размер окна. Который будет генерировать события рисования для метки, а также элемент управления контейнера, который является родительским для элемента управления меткой. Который снова проходит ту же самую процедуру, теперь фактически рисует пиксели. Который, когда Aero включен, изменяет байты в контексте устройства памяти, которое необходимо перенаправить в драйвер видеоустройства, который фактически обновляет видеопамять, чтобы пользователь мог видеть результат.

Да, это занимает время.

Ускорьте его, написав собственный код вместо того, чтобы Windows Forms делала это за вас. Переопределите событие OnPaint, используйте TextRender.DrawText для рисования меток. Быстрая победа там, это легко в 50 раз быстрее. Минус удобство конструктора в виде точки и щелчка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...