BackgroundWorker для обновления графического интерфейса - PullRequest
2 голосов
/ 30 ноября 2011

В моем приложении Silverlight у меня есть операция, которая занимает пару секунд и тесно взаимодействует с GUI (создание экранных объектов в большом операторе «for»)

Сначала я подумал об использовании BackgroundWorker, чтобы избежать зависания интерфейса. Но я не могу обновить графический интерфейс напрямую, поэтому я использовал Dispatcher.BeginInvoke, но он по-прежнему замораживает интерфейс (поскольку длинные действия выполняются в части графического интерфейса).

Я бы хотел, чтобы отображался BusyIndicator во время загрузки моих объектов, но я хочу, чтобы пользователь мог продолжать работу во время загрузки.

Что еще я могу сделать? Есть предложения?

Ответы [ 2 ]

5 голосов
/ 30 ноября 2011

Даже значок занятости здесь вам не поможет. Занятые значки или любой другой графический элемент требуют потока пользовательского интерфейса для прокачки сообщений, чтобы не «заморозить» пользовательский интерфейс. Если ваши длительные операции выполняются в потоке пользовательского интерфейса, то даже занятый курсор «зависнет».

Вам нужно либо

  1. Переместить дорогостоящую долгосрочную логику в фоновый поток
  2. Разбейте логику пользовательского интерфейса на куски и дайте интерфейсу обновиться между ними.
4 голосов
/ 30 ноября 2011

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

Я предполагаю, что большая часть работы в BackgroundWorker заключается не в создании элементов, а в дополнительной обработке, которая происходит для создания элементов пользовательского интерфейса в середине всего остального. Если это так, вам нужно разбить фактическую генерацию элементов пользовательского интерфейса. Замените создание элементов пользовательского интерфейса на фиктивные классы, которые содержат все спецификации, необходимые для создания всех элементов. Затем вы возвращаете эту коллекцию спецификаций (фиктивные классы) и генерируете фактические элементы в событии BackgroundWorker.RunWorkerCompleted.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...