Есть ли альтернативы для вызова в WPF при передаче данных из другого потока? - PullRequest
2 голосов
/ 27 марта 2012

Я знаю, как передавать данные из рабочего потока в основной поток через Invoke / BeginInvoke. Я также могу извлечь из многопоточной коллекции с таймером из основного потока. Я предпочитаю использовать задачи (Task.Factory.StartNewTask ()) и использовать Backgroundworker с их швами немного неуклюже.

Иногда графический интерфейс немного запаздывает из-за (Begin) Invoke, который я предполагаю. Вытягивание с помощью таймера также не кажется правильным. Создание нового Backgroundworker для каждой новой задачи выглядит также странно.

Есть ли другие возможности?

1 Ответ

3 голосов
/ 27 марта 2012

В .NET память разделяется внутри домена приложений, что означает, что все потоки могут получить доступ ко всем данным.Итак, на самом деле вы управляете доступом к определенным битам данных из определенных потоков, чтобы они не мешали друг другу.

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

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

Если это происходит, вы должны снизить скорость отправки сообщений.Есть несколько способов сделать это:

1) Вызывать Invoke реже: это означает ожидание больших "кусков" изменений состояния в фоновом потоке, прежде чем он вызовет Invoke для обновления пользовательского интерфейса.

2) Используйте таймер пользовательского интерфейса: нет смысла пытаться обновить пользовательский интерфейс быстрее, чем может обнаружить человеческий глаз.Таймер пользовательского интерфейса также отправляет сообщения Windows в цикл сообщений пользовательского интерфейса, но с известной скоростью.Затем обработчик Tick может извлечь необходимые данные из общей памяти для обновления пользовательского интерфейса.

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

...