|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
Есть код расчёта. Есть код отрисовки, который работает по результатам этого расчёта. Всё это запускается в цикле несколько раз. Расчёт идёт меньше секунды, а отрисовка - может до нескольких секунд доходить. Проблема в том, что UI отображает только конечный результат отрисовки - после всех проходов цикла. А промежуточные не отображает. Как сделать так, чтобы расчёт ждал отрисовку? Отрисовка идёт с помощью графиков из Dynamic Data Display. Пробовал: 1. Усыпить текущий поток (Thread.Sleep) после отрисовки, но до следующей итерации цикла. - Просто UI дольше не отвечает (сколько надо для расчёта и отрисовки, плюс время сна), а результат тот же - только конечный результат. 2. Через другой поток: Thread t = new Thread(new ParametrizedThreadStart(<метод отрисовки, работающий с контролами UI>)); Пишет, что UI должен иметь доступ только из STA-потоков. Я так понимаю, что это была попытка доступа из MTA-потоков. 3. Через Dispatcher.Invoke(<метод отрисовки, работающий с контролами UI>). - Результат тот же, что и в варианте 1. 4. Через async, примерно так: var t = Task.Run(<метод отрисовки, работающий с контролами UI>); t.Wait(); Результат тот же, что и в варианте 2. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2014, 20:21 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
HomeCoderКак сделать так, чтобы расчёт ждал отрисовку? Я хочу показывать промежуточные результаты на графиках. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2014, 20:22 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
HomeCoder, показывать промежуточные результаты можно независимо от расчета (например, записать их в коллекцию, и потом отобразите). Тормозить расчет ради графиков - извините, бред. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2014, 21:20 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
Если не секрет какой тип графика Вы используете? А теперь по делу.. В биржевых терминалах обычно задают частоту, с которой вы отображаете данные, т.е. вы всегда рисуете некий снапшот.. А если принять во внимание физиологию восприятия, то и отображать чаще чем 5-7 раз в секунду и смысла нет.. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.07.2014, 17:23 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
NewBarbarianЕсли не секрет какой тип графика Вы используете? Я уже разобрал примеры, прилагаемые к Dynamic Data Dysplay. Там всё упирается в то, что за раз отобразить более 1000 точек моя машинка не может без тормозов. Т. е. можно добавлять к графику, уже имеющему хоть 100 000 точек, по 1000 точек в секунду. Тогда почти не тормозит. А вот если за раз добавлять существенно более, чем 1000 (скажем, 5000), то тормозит. Из этого можно сделать вывод, что сам DirectX успевает перерисовывать все 100 000 точек графика. А вот WPF не успевает отрисовать дополнительно даже 5000 с приемлемой скоростью. Это связано, во первых, с неэффективностью отрисовок в WPF, а во-вторых - с retained-моделью графики в WPF. Чтобы перерисовать картинку, WPF должен сначала "отвязать" модель (данные, которые надо отрисовать, включая контролы, изображения и прочая визуальная часть) от кода отрисовки, изменить модель, потом снова привязать модель к коду отрисовки - примерно такое упрощённое объяснение я встречал. Т. е. в самом WPF нет некоего непрерывного цикла перерисовки, как в DirectX или XNA. Графики я использую обычные - LinearGraph - примерное название. А вот добавление новых точек делаю в другом потоке. Но при этом в этом другом потоке нужно использовать Dispatcher, иначе будет ошибка, что вы не можете получить доступ в графику, т. к. им владеет поток UI. В Диспетчер передаём делегат, который и добавляет (через метод AppendMany) новые точки в уже существующий график. При этом, чтобы WPF успевал отрисовывать, поток, которые добавляет новые точки, я в конце немного усыпляю. Для 1000 точек за раз примерно 1 секунды сна достаточно на моей машине. Если не будете усыплять поток, то WPF будет просто пропускать, исключать из отрисовки те акты добавления новых точек, которые следуют за теми, которые он не успевает отрисовывать. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.07.2014, 20:26 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
авторИз этого можно сделать вывод, что сам DirectX успевает перерисовывать все 100 000 точек графика. А вот WPF не успевает отрисовать дополнительно даже 5000 с приемлемой скоростью. Это связано, во первых, с неэффективностью отрисовок в WPF, а во-вторых - с retained-моделью графики в WPF. Чтобы перерисовать картинку, WPF должен сначала "отвязать" модель (данные, которые надо отрисовать, включая контролы, изображения и прочая визуальная часть) от кода отрисовки, изменить модель, потом снова привязать модель к коду отрисовки - примерно такое упрощённое объяснение я встречал. Т. е. в самом WPF нет некоего непрерывного цикла перерисовки, как в DirectX или XNA. Я, конечно, не знаю точно кода отрисовки внутри WPF. Но думаю, что он выглядит примерно так. Когда надо отправить данные на отрисовку в DX, WPF вмешивается в цикл отрисовки DX, чтобы создать нужные вершины, индексы, текстуры и прочее. Когда всё готово и если от кода не поступает новых требований по изменению отрисовываемой модели, то WPF не вмешивается в цикл отрисовки. В это время проихсодит так называемое удержание модели в подсистеме отрисовки DX - поэтому и модель такая называется удерживающей (retained). Если надо изменить модель (код поменял размеры кнопки, или включил анимацию, или поменял значение в текстбоксе и т. п.), WPF снова вмешивается в цикл орисовки. Почему в WPF тормозят анимации. WPF не работает с возможностями DX 10 и старше. Более того, он и возможности DX 9 не полностью использует. Система отрисовки WPF (система взаимодействия с DX) в WPF была написана очень давно - ещё в 2008 году и даже раньше. Тогда не было всяких геометрических шейдеров, либо создатели WPF посчитали, что их использование в WPF излишне. Поэтому все анимации в WPF выполняются постоянными вмешиваниями в цикл отрисовки. Т. е. WPF при анимациях постоянно меняет цикл отрисовки, привязывая и отвязывая модель на каждый кадр. Т. е. нарисовали всю модель, отвязались, отрендерили кадр через DX. Потом снова привязались к модели, поменяли координаты анимируемых объектов, отвязались и снова отрендерили. Всё это жутко тормозит. Т. е. такой механизм реализации анимаций жутко неэффективен. Но исправлять это в WPF никто не хочет - приоритеты у МС теперь другие. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.07.2014, 20:36 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
Так может лучше не прогонять через диспатчер каждый тик данных, а накапливать блоки допустим по 100 мс, а потом отображать.. Еще такой вопрос.. В видимой области находятся все 100000 точек? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.07.2014, 01:42 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
NewBarbarianТак может лучше не прогонять через диспатчер каждый тик данных, а накапливать блоки допустим по 100 мс, а потом отображать.. Еще такой вопрос.. В видимой области находятся все 100000 точек? Там проблема не в диспетчере. Хоть с ним, хоть без него пробовал уже много раз - проблема именно в WPF, когда ему нужно отобразить НОВЫЕ данные - т. е. когда он вмешивается в цикл отрисовки DX. В видимой области постоянно находятся все ранее добавленные данные. У меня это доходит до примерно 130 000 точек. Т. е. добавить НОВЫЕ данные к уже имеющимся - ограничение на количество добавляемых НОВЫХ данных. Иначе тормозит. Если дадите команду перерисовать весь график, то новыми данными станут ВСЕ данные графика - 130 000 точек он будет отрисовывать несколько секунд. Естественно, это зависит от CPU и GPU. Хотя, на мой взгляд, больше от CPU, т. к. вмешательство в цикл отрисовки DX происходит именно за счёт CPU. А GPU хватит даже самого дешёвого, которые сейчас есть на рынке. Я просто немного разбирался в графике WPF и его 3D возможностях, читал, чем они ограничены. Плюс в DX пытаюсь сейчас разобраться. И до меня постепенно доходит, в чём в этом WPF собака зарыта. Как я понял, основная проблема - код отрисовок в цикле DX был написан очень давно и неоптимально, а также не использовал новые возможности DX и современных (тогда) видеокарт. Ну и плюс современные (сегодня) возможности он, конечно же, не использует, как то геометрические шейдеры, которые позволили бы WPF делать анимации прямо в видеокарте, а не постоянным вмешательством и перерисовками анимируемых объектов "софтовым методом" (т. е. на CPU). И МС не хочет этот код переписывать-оптимизировать, т. к. на WPF поставлен крест. И уже давно. Я думаю, МС уже году так в 2010 знала, что не будет поддерживать больше WPF - с тех пор, как у них был взят тренд на разработку WinRT и нового замл-фреймворка для интерфейсов - с плитками и прочим. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.07.2014, 07:18 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
HomeCoder, Мне понравилось разьяснение на пальцах здесь a-critical-deep-dive-into-the-wpf-rendering-system ... |
|||
:
Нравится:
Не нравится:
|
|||
10.07.2014, 15:21 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
gpuHomeCoder, Мне понравилось разьяснение на пальцах здесь a-critical-deep-dive-into-the-wpf-rendering-system Да, неплохо объяснено. Это у меня на пальцах, а там с примерами. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.07.2014, 20:03 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
HomeCoder, В книжках написано, что может помочь BitmapCache. Код: xml 1. 2. 3.
Мне не помогло. Может Вам повезет больше? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.07.2014, 11:22 |
|
WPF - отрисовка не успевает за вычислениями
|
|||
---|---|---|---|
#18+
Cat2HomeCoder, В книжках написано, что может помочь BitmapCache. Код: xml 1. 2. 3.
Мне не помогло. Может Вам повезет больше? На всякий случай improving-wpf-rendering-performance ... |
|||
:
Нравится:
Не нравится:
|
|||
14.07.2014, 14:18 |
|
|
start [/forum/topic.php?fid=21&fpage=22&tid=1441087]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
71ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 165ms |
0 / 0 |