2012-03-31 3 views
7

В моем приложении WPF я загружаю контент, используя Dispatcher.BeginInvoke в конструкторе. Мой вопрос: будет ли он блокировать поток пользовательского интерфейса?В чем разница между Dispatcher.BeginInvoke и Task.Factory.StartNew

Или лучше использовать Task.Factory.StartNew, а затем отправлять информацию обратно в пользовательский интерфейс, чтобы приложение загружалось первым независимо от времени загрузки содержимого загрузки?

Какой подход лучше и почему?

ответ

20

Они делают две совершенно разные вещи:

  • Task.Factory.StartNew графиков делегата для выполнения на пула потоков в нити. Текущий поток продолжает работать, не дожидаясь результата этой задачи (async). Как правило, вы создавали бы более длинную рабочую фоновую задачу, чтобы пользовательский интерфейс не был слишком долго заблокирован (а не «заморожен»).

  • Dispatcher.BeginInvoke планирует делегат для выполнения на потоке диспетчера . Обычно это делается для обновления некоторых элементов управления UI с результатами некоторой операции, выполненной в фоновом потоке . По сути, вы обновляете пользовательский интерфейс здесь.

Чтобы ответить вам вопросы напрямую:

Вы не должны планировать длительные операции на Диспетчерский нити, как правило, вы только хотите, чтобы обновить интерфейс управления здесь. Код в делегате будет выполнен в потоке пользовательского интерфейса, который блокируется на время выполнения. Просто поместите Thread.Sleep(10000) в свой текущий код (который вы планируете из конструктора), и вы увидите, что пользовательский интерфейс замерзнет. Для этого воспользуйтесь фоновой задачей - либо с помощью Task, либо фонового работника (оба будут использовать поток пула потоков).

Или лучше использовать Task.Factory.StartNew, а затем диспетчерская вещи обратно на UI, так что приложение будет загружать первый независимо от время процесса загрузки контента.

Да!

+0

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

+2

если вы хотите, чтобы что-то работало на * фоне *, используйте задачу, если вы хотите отправить результаты в пользовательский интерфейс, используйте 'Dispatcher.BeginInvoke' – BrokenGlass

Смежные вопросы