Есть ли альтернатива использованию Background Worker в WPF? - PullRequest
6 голосов
/ 10 августа 2011

Я новичок в WPF, в моем приложении мне нужно выполнить ряд шагов инициализации, выполнение которых занимает 10-15 секунд, в течение которых мой пользовательский интерфейс перестает отвечать на запросы.

Вчера я использовал фонрабочий, но он не обновил мое окно, фактически он был заморожен.Не уверен, но, возможно, это не сработало, потому что этот элемент управления только для Windows Forms.

ОБНОВЛЕНИЕ:

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

Ответы [ 3 ]

6 голосов
/ 10 августа 2011

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

Диспетчер не всегда является альтернативой BackgroundWorker.Лучшая практика заключается в выборе более подходящего в соответствии с вашими требованиями.Например, если вы хотите, чтобы что-то выполнялось без постановки в очередь, BackgroundWorker - это решение.С другой стороны, если организация очередей не является проблемой, Dispatcher является альтернативой.Например, Dispatcher использует функции проверки орфографии и подсветки синтаксиса.

Модель потока WPF

Все приложения WPF запускаются сдва важных потока, один для рендеринга и один для управления пользовательским интерфейсом.Поток рендеринга - это скрытый поток, который работает в фоновом режиме, поэтому единственный поток, с которым вы обычно имеете дело, это поток пользовательского интерфейса.WPF требует, чтобы большинство его объектов были связаны с потоком пользовательского интерфейса.Это называется привязкой к потоку, то есть вы можете использовать объект WPF только в том потоке, в котором он был создан.Использование этого в других потоках вызовет исключение времени выполнения.Обратите внимание, что модель потоков WPF хорошо взаимодействует с API на основе Win32®.Это означает, что WPF может размещаться или размещаться с помощью любого API на основе HWND (Windows Forms, Visual Basic®, MFC или даже Win32).

Связанность потоков обрабатывается классом Dispatcher, приоритетным циклом сообщений для приложений WPF.Как правило, ваши проекты WPF имеют один объект Dispatcher (и, следовательно, один поток пользовательского интерфейса), через который направляется вся работа пользовательского интерфейса.

ПРИМЕЧАНИЕ:

Основное различие междуDispatcher и другие методы работы с потоками заключаются в том, что Dispatcher на самом деле не является многопоточным.Диспетчер управляет элементами управления, которым для правильной работы требуется один поток;метод BeginInvoke для Dispatcher ставит в очередь события для последующего выполнения (в зависимости от приоритета и т. д.), но все еще в том же потоке.

См. этот поток для получения дополнительной информации.*

0 голосов
/ 10 августа 2011

Можно использовать асинхронные делегаты.

http://msdn.microsoft.com/en-us/library/ms228963.aspx

Просто убедитесь, что если вы делаете какие-либо обновления, связанные с пользовательским интерфейсом, используйте:

Dispatcher.CheckAccess()

Вот простой пример:

private void HandleUIButtons()
{    
    if (!btnSplit.Dispatcher.CheckAccess())   
    {         
        //if here - we are on a different non-UI thread        
        btnSplit.Dispatcher.BeginInvoke(new Action(HandleUIButtons));    
    }    
    else        
    {
        btnSplit.IsEnabled = true; //this is ultimately run on the UI-thread
    }
}

взято отсюда:

http://blog.clauskonrad.net/2009/03/wpf-invokerequired-dispatchercheckacces.html

0 голосов
/ 10 августа 2011

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

...