2010-02-28 6 views
3

Один из шаблонов, используемых с асинхронными делегатами, также является шаблоном обратного вызова, где начальный поток (тот, который называется BeginInvoke) T1 продолжается, не дожидаясь или проверяя, завершен ли порожденный поток T2. Вместо этого, когда T2 завершен, T2 вызывает метод обратного вызова, который обрабатывает результаты, вызывает EndInvoke и информирует T1 о завершении задачи.Когда асинхронные делегаты используют шаблон обратного вызова?

a) Если метод обратного вызова должен сообщать T1, когда задача завершена, то почему этот метод обратного вызова не вызван внутри T1, а не T2?

2) Есть ли стандартный шаблон, как метод обратного вызова должен информировать T1 о завершении T2?

3) Должен ли использоваться обратный вызов, даже если T1 должен получить возвращаемое значение асинхронно называемого метода?

Thanx

+0

Зачем T1 давать дерьмо о том, что происходит в T2? Нити - это не что иное, как контексты исполнения; Для T1 не имеет значения, что происходит в T2. Важно, что после того, как приложение вошло, и только до тех пор, пока оно не войдет в состояние X, которое Y не произойдет. Почему Y должен выполняться T1 (кроме исключения пользовательского интерфейса)? – Will

ответ

3
  • почему не метод обратного вызова вызывается в T1?

Вообще это невозможно; если T1 выключен, выполняя какую-то другую работу, нет возможности перенаправить на него работу, если в потоке уже нет механизма для публикации и планирования работы (например, поток пользовательского интерфейса через SynchronizationContext).

  • Есть ли стандартный шаблон для уведомления о перекрестном потоке?

Я бы сказал: нет; существует несколько шаблонов синхронизации кросс-потоков, которые применяются к различным целевым сценариям.

  • Что делать, если T1 нуждается в возвращаемом значении?

Если T1 нуждается в возвращаемом значении под текущим стеком, то в конечном итоге его придется заблокировать, чтобы его получить. Блокировка может произойти, вызвав EndInvoke, используя WaitHandle или другие стратегии из предыдущей пули.

Если вещь, которая нуждается в возвращаемом значении, является «просто потоком» (например, потоком пользовательского интерфейса), но не под конкретным контекстом вызова/активации, тогда обычно SynchronizationContext.Post или Dispatcher.Invoke используется для маршаллинга работы в конечном итоге вернитесь к потоку пользовательского интерфейса, когда он будет готов.

+0

Я предполагаю, что если T2 должно сообщить T1, что оно закончено, то реализация метода обратного вызова (т. Е. Шаблон обратного вызова) не дает преимуществ по шаблону опроса (где T1 периодически проверяет через IsCompleted свойство, завершился ли порожденный поток), и поэтому мы должны вместо этого реализовать шаблон опроса? – AspOnMyNet

3

Предоставление кода запуска потока в другом потоке довольно нетривиально. Но это обычное требование для приложений Windows Forms и WPF, компоненты пользовательского интерфейса никогда не являются потокобезопасными. Они do имеют общий шаблон для него, соответственно Control.Invoke и Dispatcher.Invoke. И есть стандартный вспомогательный класс, BackgroundWorker. Он вызывает события в потоке пользовательского интерфейса, это аналог метода обратного вызова - это событие RunWorkerCompleted.

Вы можете, конечно, использовать собственный механизм, если вы предпочитаете использовать метод BeginInvoke(), но получить это право может быть сложно.

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