Как асинхронный вызов знает, когда начинать завершенное событие в новом потоке или использовать поток вызывающего - PullRequest
1 голос
/ 16 марта 2011

Допустим, у нас есть сервис TestService с методом DoWork. На клиенте он сгенерирует методы DoWorkCompleted и DoWorkAsync.

Это мое наблюдение, если вы вызываете DoWorkAsync из потока пользовательского интерфейса, DoWorkCompleted будет выполняться в потоке пользовательского интерфейса, как и ожидалось.

Но если я запускаю BackgroundWorker и вызываю службу DoWorkAsync из нее, тогда DoWorkCompleted выполняется в новом потоке, отличном от потока вызывающего. Пример:

  1. Запустить BackgroundWorker экземпляр <- Из пользовательского интерфейса </li>
  2. Рабочий DoWork метод выполняется <- Тема 2 </li>
  3. Позвонить в сервис DoWorkAsync от рабочий DoWork <- из потока 2 </li>
  4. Служба запускается и DoWorkCompleted исполняется <- Тема 3 </li>
  5. рабочий DoWorkCompleted получает выполнено <- поток пользовательского интерфейса </li>

Как клиент службы узнает, когда начинать новую тему и когда отправлять ее обратно в ветку вызывающей стороны?

1 Ответ

3 голосов
/ 16 марта 2011

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

В вашем первом сценарии, поскольку вы вызываете DoWorkAsync из потока с доступным контекстом синхронизации, DoWorkCompleted перенаправляется обратно в исходный поток.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...