В чем разница между Dispatcher.BeginInvoke и Task.Factory.StartNew - PullRequest
8 голосов
/ 31 марта 2012

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

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

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

1 Ответ

22 голосов
/ 31 марта 2012

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

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

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

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

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

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

Да!

...