движения мыши для фонового потока созданных оконных форм

Мне интересно, возможно ли 1) Размещение фонового потока, созданного в форме окна, внутри основного потока приложения, созданного в форме окна? или 2) Отделить поток, который обрабатывает движения мыши, от потока, рисующего приложение формы Windows?

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

Наша команда разработчиков программного обеспечения пишет несколько плагинов для стороннего приложения формы Windows. Итак, мы предоставляем корневую основную форму, в которой размещается множество пользовательских элементов управления, используя их API, и они размещают их в своей собственной форме Windows. В настоящее время все пользовательские интерфейсы создаются в основном потоке приложения, поэтому они хорошо взаимодействуют друг с другом. Многие из наших пользовательских элементов управления, которые мы предоставляем, имеют диаграммы system.windows.forms.datavisualisation, которые рисуются в реальном времени данными, которые получает приложение. Одна из проблем, с которой мы сталкиваемся, заключается в том, что когда пользователь хаотично перемещает мышь, дисплей перестает обновляться, поскольку вся прорисовка графиков (GDI+) выполняется в основном потоке (мы используем фоновые потоки и TPL для поиска и вычисления данных, но рисование выполняется в основном потоке). Поэтому мне интересно, можно ли сделать так, чтобы вся рисование gdi+ этих диаграмм происходило в потоке, отличном от основного потока приложения, чтобы рисование продолжалось, и мы все еще могли получать входные данные движения мыши и щелчки для взаимодействия с пользователем, но неустойчивая мышь движения не могут заполнять очередь сообщений и останавливать отрисовку gdi+ пользовательских элементов управления.

Любая помощь, особенно указатели на соответствующие API или статьи, демонстрирующие методы, будут высоко оценены. Спасибо.


person Comic Book Guy    schedule 30.05.2014    source источник
comment
анонимное голосование против - отстой и трусость. :-)   -  person Comic Book Guy    schedule 30.05.2014
comment
Согласен, +1 в качестве компенсации :)   -  person A.J. Uppal    schedule 30.05.2014


Ответы (1)


Это зависит от причины замедления при завершении розыгрыша.

Во-первых, вы должны оптимизировать свои процедуры рисования, может быть, вы рисуете всю форму/элемент управления при каждом вызове OnPaint? Если это так, вам следует перерисовать только недействительную область, что значительно ускорит работу.

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

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

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

В качестве примера предположим, что у вас есть элемент управления, в котором вы рисуете градиентный фон и круг.

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

Чтобы сделать это в фоновом режиме, если вы создали растровое изображение как внеэкранный буфер, вы не рисуете на поверхность, вы рисуете растровое изображение в другом потоке (получая из него графический объект), а затем аннулируете обновленную область элемента управления. . Когда вы аннулируете область, будет вызываться OnPaint, а затем вы можете перенести это растровое изображение на поверхность элементов управления.

На этом шаге вы практически не увеличили скорость, но давайте расширим наш пример. Предположим, вы рисуете очень сложный элемент управления с большим количеством вызовов DrawImage, DrawCircle и т. д. Когда мышь перемещается по элементу управления, небольшие области становятся недействительными, и при каждом вызове OnPaint вы будете рисовать все «слои», составляющие недействительную область. , это может быть много розыгрышей, если, как мы сказали, управление очень сложное.

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

Надеюсь, это проясняет мысль.

person Gusman    schedule 30.05.2014
comment
Спасибо за совет. мы делаем рендеринг в фоновые буферы, используя фоновый поток и блит, как вы упомянули, для настраиваемых окрашенных экранов, наряду с выборочной недействительностью, однако форма корневых окон имеет свойство двойной буферизации, установленное на true, и я думаю, что то же самое делают все пользовательские элементы управления, возможно, это контрпродуктивно, у вас есть какой-нибудь совет, если это означает, что обратных буферов слишком много? также выполняется много рисунков, мои элементы управления Windows Forms и mscharts я не уверен, как я могу заставить их рисовать на растровом изображении и блицировать, за исключением использования свойства двойной буферизации, это возможно? - person Comic Book Guy; 30.05.2014
comment
Расширенный ответ для уточнения концепции. - person Gusman; 30.05.2014