Многопоточный рисунок в .NET? - PullRequest
6 голосов
/ 25 июля 2010

( Редактировать : чтобы уточнить, моя главная цель - параллелизм, но не обязательно для многоядерных машин)

Я довольно новичок во всех концепцияхпо параллелизму, но я понял, что мне нужно иметь параллельные процедуры рисования по ряду причин:

  • Я хотел рисовать разные части графики отдельно (фон обновлялся реже, чем передний план, оставался набуфер).
  • Мне нужен контроль над приоритетом (больший приоритет для отзывчивости пользовательского интерфейса, чем для рисования сложного графика).
  • Я хотел, чтобы расчеты рисования по кадрам были многопоточными.
  • Я хотел предложить отмену для сложных процедур рисования в буфере.

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

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

Любое предложение приветствуется , но у меня естьпредпочтение источников, которые я могу переварить в свободное время (например, не более 500 страниц трактата о параллелизме) и C # / VB.NET, до последней версии (так как я вижу, что было достижений)).По сути, я хочу что-то прямо в точку, чтобы я мог начать играть с концепциями моих игрушечных проектов.

Ответы [ 2 ]

9 голосов
/ 25 июля 2010

но я понял, что мне нужно процедуры параллельного рисования

Три слова: НЕ ПОД ОКНАМИ.

Просто так. Стандартное рисование окон является однопоточным по определению, из соображений совместимости. Любой элемент управления пользовательского интерфейса (давайте придерживаться мира .NET) должен управляться ТОЛЬКО из его потока создания (так что в действительности он более жесток, чем однопоточный - это ТОЛЬКО ОДНА СПЕЦИФИЧЕСКАЯ РЕЗЬБА).

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

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

Это не имеет ничего общего со всей библиотекой параллельных задач и т. Д. (За которую я отказался), но возвращает город к очень старому требованию, которое соблюдается по причине простоты И совместимости. Это причина, по которой любой поток пользовательского интерфейса должен продаваться в виде двухпоточных аппартаментов.

Также обратите внимание, что многопоточный чертеж, если вы реализуете его самостоятельно, имеет серьезные последствия. Какой из них выигрывает оптически (остается на переднем плане)? Это не совсем определимо при использовании многопоточных. Вы можете это попробовать.

В этом случае:

  • Наличие собственного буфера и синхронизации обязательно. Держитесь подальше от любой графической библиотеки на уровне окон (WPF или Winforms), за исключением последнего шага (создание растрового изображения).

  • DirectX 11 предположительно имеет некоторую поддержку многопоточных вызовов, но я не уверен, насколько далеко это зашло.

1 голос
/ 25 июля 2010

Библиотека параллельных задач определенно предназначена для упрощения вашего кода. Я лично написал (полудлинное) введение в Параллелизм с .NET 4 , которое охватывает довольно много полезных понятий.

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

Большинство API рисования требуют, чтобы все реальные вызовы рисования происходили в одном и том же контексте синхронизации.

При этом использование новых классов коллекций, таких как ConcurrentQueue , упрощает этот тип кода. Попытайтесь думать с точки зрения множества потоков (производителей), добавляющих «операции рисования» в общую параллельную очередь, и одного потока (потребителя), захватывающего операции и выполняющего их.

Это дает вам достаточно масштабируемую, но довольно простую конструкцию, на которой вы можете строить.

...