В каком потоке работают асинхронные обратные вызовы? - PullRequest
1 голос
/ 03 апреля 2011

Я делаю несколько HttpWebRequest.BeginGetResponse вызовов, и в методе обратного вызова BeginGetResponse я вызываю EventHandler. В EventHandler есть логика для проверки успешности загрузки. Если нет, он пытается повторно загрузить HTML. Я заметил, что генерируется много потоков, особенно когда есть ошибки. Итак, в каком потоке выполняются асинхронные обратные вызовы?

Есть ли способ вызвать EventHandler в исходном потоке? Если это невозможно, могу ли я вызвать его в потоке пользовательского интерфейса?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 03 апреля 2011

Что вы подразумеваете под "в оригинальной теме"? Какой оригинальный поток? Вы можете маршалировать в поток пользовательского интерфейса, используя Control.BeginInvoke или Dispatcher.BeginInvoke. Вы не можете направить произвольный поток - он должен иметь что-то , как насос сообщений, ожидающий работу.

Что касается того, в каком потоке HttpWebRequest выполняются асинхронные обратные вызовы - я бы ожидал либо рабочий поток общего пула потоков, либо, возможно, поток порта завершения ввода / вывода.

3 голосов
/ 03 апреля 2011

Обратные вызовы выполняются в потоке потоков.В .NET нет механизма, позволяющего запускать код в определенном потоке.Это очень трудно понять, вы не можете просто прервать поток, пока он занят, и заставить его выполнить некоторый код.Это вызывает ужасные проблемы повторного входа, которые блокировка не может решить.

Поток должен находиться в состоянии бездействия, не активно изменяя состояние программы.Есть один вид потока, который ведет себя таким образом, поток пользовательского интерфейса в приложении Winforms или WPF.Это также поток, который имеет дело с объектами, которые в основном не поддерживают поток, что-либо, связанное с пользовательским интерфейсом.Это не совпадение.

Обе библиотеки классов позволяют перенаправлять вызов из рабочего потока в поток пользовательского интерфейса, в частности, чтобы обновить пользовательский интерфейс безопасным для потока способом.В Winforms вы используете Control.Begin / Invoke (), в WPF вы используете Dispatcher.Begin / Invoke ().BackgroundWorker - удобный класс для выполнения этого без явного управления маршалингом.Но не подходит для обратных вызовов завершения ввода / вывода.

1 голос
/ 04 апреля 2011

Используя шаблон Begin / End Async, имейте в виду, что многие задачи могут выполняться в потоке, из которого они были вызваны.Когда вы вызываете BeginXXX, он возвращает логическое значение, которое указывает, была ли задача выполнена в вызывающем потоке или нет.

Основной ответ - это может быть любой поток.

0 голосов
/ 03 апреля 2011

Если вы используете WPF, вы можете использовать Dispatcher для вызова вашей логики в потоке пользовательского интерфейса.

В противном случае (если не в WPF) вы можете использовать SyncrhronizationContext для выполнения того же действия.

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