Использование вызовов Win32 API через классы .NET GDI

У меня есть приложение winforms, разработанное на С#, которое требует большого количества рисунков на экране. Рисование включает в себя визуализацию пользовательских элементов управления и других 2D-объектов. Теперь проблема в том, что для рисования всего экрана требуется примерно 4-5 секунд. Я оптимизировал код до уровня, при котором все необходимые данные доступны в самой памяти, а не считываются с диска или из сети.

Чтобы еще больше сократить время рендеринга, я планировал использовать следующие варианты.

  1. Вызывайте напрямую функции GDI, предоставляемые Win32API, вместо использования классов GDI, предоставляемых .NET.

  2. Используйте DirectX, так как я слышал, что он очень эффективен при рендеринге. Мое приложение не требует какого-либо 3D-рендеринга.

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


person AbrahamJP    schedule 14.02.2012    source источник
comment
Сколько у вас элементов управления? Сотни?   -  person Hans Passant    schedule 14.02.2012
comment
@HansPassant: от 5 до 7 тысяч элементов управления   -  person AbrahamJP    schedule 14.02.2012
comment
Вау, удивительно, это занимает всего 7 секунд. Вам придется сократить это до 100 или около того.   -  person Hans Passant    schedule 14.02.2012
comment
@HansPassant: я рисую элементы управления и проверяю попадание при нажатии, чтобы элементы управления казались интерактивными. Пожалуйста, дайте мне знать ваше мнение о вызовах Win32 API или что-то вроде использования небезопасных блоков, будет ли это иметь какое-то значение?   -  person AbrahamJP    schedule 14.02.2012


Ответы (1)


Из личного опыта:

  • GDI+ медленнее GDI всего в ‹ 2 раза. Переход с .NET (который использует GDI+) на чистый GDI не сильно поможет.

  • Direct2D такой же медленный, как и GDI, по крайней мере, для рисования основных фигур. Поэтому, если вы не делаете что-то более сложное, это, вероятно, не поможет.

Лучше всего, вероятно, сократить чертеж и выполнить двойную буферизацию данных.

Если это не сработает, вы, вероятно, захотите сгенерировать растровое изображение в памяти (используя byte[] или что-то еще, полностью избегая графических API) и просто скопировать (скопировать) его прямо на экран. Это тяжело, но почти всегда оказывается самым быстрым.

person user541686    schedule 14.02.2012
comment
Спасибо за ваш вклад, пожалуйста, дайте мне знать, было бы разумно использовать прямые вызовы API Win32, потому что я чувствую, что могу пропустить некоторые слои .NET, которые могут повысить производительность на несколько миллисекунд. - person AbrahamJP; 14.02.2012
comment
@AbrahamJP: Как я уже упоминал, это может сократить секунду или максимум две, но это все равно не будет удовлетворительным. - person user541686; 14.02.2012