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