Вопрос

...или...

«Какое зло в глубинах WPF я пробудил?»

Я создаю Canvas в фоновом потоке и преобразую его в растровое изображение.У меня это работает в производственном коде уже больше года без проблем.Я делаю следующее:

  • создать объект Canvas
  • создать новый объект NameScope
  • назначьте этот NameScope Canvas
  • рисую на холсте все, что захочу
  • вызов Canvas.Measure() с размером Canvas
  • вызов Canvas.Arrage() с доступным прямоугольником Canvas
  • вызвать холст.UpdateLayout()
  • визуализировать холст

На этапе рисования я всегда просто вызывал Canvas.Children.Add(), чтобы поместить UIElements на Canvas.Это всегда работало.

Теперь по какой-то необъяснимой причине в одном конкретном случае в приложении, над которым я работаю, вызов Canvas.Children.Add() зависает на неопределенный срок, блокируя мой фоновый поток.Я не могу вспомнить, что я делаю по-другому между кодом, который работает больше года, и этим конкретным случаем.

Может ли кто-нибудь предложить возможные причины, по которым вызов Canvas.Children.Add() зависает вот так?

Редактировать:Фоновым потоком является поток STA (модель обработки фонового потока была введена, потому что я не мог обрабатывать изображения с помощью WPF в потоке MTA), поэтому модель подразделения потоков не должна быть виновником.

Редактировать №2:Хотя я понимаю, почему люди предлагают мне попробовать Dispatcher.BeginInvoke() из моего фонового потока, мне не нравится этот вариант по двум причинам:

  1. Я хочу, чтобы моя фоновая обработка потока была синхронной в этом потоке.В моем фоновом потоке есть очередь, в которую другие потоки отправляют задания изображений, а мой фоновый поток обрабатывает каждое задание по мере его поступления.Использование Dispatcher.BeginInvoke() добавляет еще один уровень сложности, которого я бы предпочел избегать.
  2. Я ни разу нужно до настоящего времени.Выполнение этой фоновой обработки синхронно в моем фоновом потоке просто работал.Я пытаюсь определить, что может быть особенного в этом странном крайнем случае, из-за которого этот код не работает.Если я не смогу заставить его работать, мне придется переписать этот код обработки без WPF, чего я бы предпочел избежать.
Это было полезно?

Решение

Какую модель квартиры вы используете в качестве фоновой темы?

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

Обновлять:

Если проблема не в потоке STA, я бы попробовал разбить ваш рисунок холста на куски.В основном, если вы делаете:

Диспетчер.BeginInvoke(...)

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

Обновление 2:

Вы также можете попробовать выполнить отладку исходного кода объекта Canvas, используя справочные источники платформы .NET.Вы можете включить это, включив «включить пошаговое изменение исходного кода .net framework» в параметрах отладки в разделе «Инструменты» -> «Параметры».

Другие советы

Попробуйте вызвать Dispatcher.Run() в фоновом потоке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top