Как делает понятие Диспетчера в.NET 3.5, и WPF отличаются от фонового потока в.NET 2.0?
Например, что будет различием между операторами ниже:
delegate.Invoke/BeginInvoke
И
this.dispatcher.Invoke/BeginInvoke
Диспетчер можно рассматривать как очередь, в которую отправляются события; диспетчер будет работать в потоке пользовательского интерфейса и выполнять события для пользовательского интерфейса. В окнах элементы управления пользовательского интерфейса могут быть изменены только потоком, который их создал, поэтому любые изменения пользовательского интерфейса должны выполняться из потока пользовательского интерфейса - таким образом, это одна из критических причин, по которым операции, изменяющие элементы окна, должны отправляться в пользовательский интерфейс. диспетчер.
Фоновый поток, в свою очередь, отличается от пользовательского интерфейса. Таким образом, все, что выполняется в одном из этих потоков, не повлияет на пользовательский интерфейс и не заблокирует его.
Концепцию BeginInvoke и Invoke можно представить следующим образом.
. Теперь, как это относится к диспетчерам и фоновым потокам, это совсем другой вопрос. Как говорит Джастин, Dispatcher обрабатывает очередь дел каждый раз, когда поток пользовательского интерфейса простаивает. Фоновый поток, который вызывает BeginInvoke в диспетчере, немедленно вернется, даже если диспетчер, возможно, не успел приступить к обработке. Если бы вместо этого использовался Invoke, фоновый поток блокировался бы, пока поток пользовательского интерфейса не завершил обработку.Обратите внимание, что в Silverlight нет Invoke для Dispatcher, и в большинстве случаев вы, вероятно, не хотите, чтобы фоновый поток блокировался, пока поток пользовательского интерфейса обрабатывает работу.
И наоборот, Delegate.BeginInvoke использует рабочие потоки в пуле потоков. Когда вы находитесь в потоке пользовательского интерфейса (или на самом деле в любом потоке), вы можете вызывать BeginInvoke и Invoke для делегата. BeginInvoke будет использовать рабочий поток для вызова делегата, используя ту же семантику, которую я описал выше. Однако Invoke не будет использовать другой поток. Он просто вызовет делегат синхронно в контексте вызывающего потока и вернется после завершения.
Будьте осторожны при использовании синхронного выполнения между потоками, поскольку это часто приводит к тупикам, если вы не очень осторожны.
Использование диспетчера для выполнения длительной операции по-прежнему вызывает ее выполнение в потоке пользовательского интерфейса, только с другим приоритетом, чем текущая операция. Проблема здесь в том, что обычно вы хотите, чтобы ваша длительная операция имела максимально возможную полосу пропускания. Работая под диспетчером, пользовательский интерфейс ограничивает вас.
Задача диспетчера - дать привязку фонового потока обратно к пользовательскому интерфейсу, чтобы вы могли, например, предоставить обновление пользовательскому интерфейсу о ходе вашей операции.
Если вы хотите запустить операцию в фоновом режиме и отложить выполнение до пользовательского интерфейса, используйте backgroundworker или новую библиотеку задач. Используйте диспетчер для маршалинга обновлений обратно в пользовательский интерфейс.
Операции, вызываемые обоими методами, будут помещены в очередь событий для выполнения в потоке пользовательского интерфейса. Invoke будет происходить синхронно и будет блокироваться до завершения операции, BeginInvoke будет происходить асинхронно, позволяя вызывающему методу продолжить выполнение.