问题究竟是什么。
我已经阅读了here给出的MSDN文章,并且(除非我是盲人),无法在任何地方看到它明确证实这一点。
为了提供更多范围,我主要提到Socket.Beginxxx
类中提供的Socket
方法。
我可以安全地假设任何AsyncCallbacks将在主线程中执行吗?假设我调用的任何Socket.Beginxxx
方法也将从主线程调用。
编辑:如果不是这种情况,当我在其中一个lock
AsyncCallbacks中修改它们时,我应该Socket.Beginxxx
包含类的私有成员吗?例如。在字典中添加项目?
答案 0 :(得分:4)
我已经阅读了这里给出的MSDN文章,并且(除非我是盲目的),无法在任何地方看到它明确证实这一点。
相关引用是(强调添加):
使用AsyncCallback委托在单独的线程中处理异步操作的结果。
回调 保证在原始线程中执行;事实上,它保证在另一个线程(即线程池线程)上运行。
尽管有其他答案,但这与SynchronizationContext
或TAP或EAP如何处理其上下文完全无关。 AsyncCallback
是APM的一部分 - 最古老的异步模式 - 它绝对没有自动线程编组。
如果不是这种情况,当我在其中一个Socket.Beginxxx AsyncCallbacks中修改它们时,是否应该锁定包含类的私有成员?例如。在字典中添加项目?
你可以。我在我的异步套接字代码中发现,将所有回调编组回一个负责所有套接字操作和相关数据的共享线程更容易。然后没有必要锁,因为所有"完成的事件"被同步到一个线程。
答案 1 :(得分:0)
没有。你的假设并不总是成立。某些框架可能会覆盖覆盖同步上下文以调用特定线程上的continuation,但在语言级别上无法保证。这就是Stephen Toub所说的(关于这个问题的very informative post):
框架可以从SynchronizationContext派生自己的上下文,并覆盖Post方法,使其更适合于所表示的调度程序。例如,对于Windows窗体,WindowsFormsSynchronizationContext实现Post以将委托传递给Control.BeginInvoke。对于WPF中的DispatcherSynchronizationContext,它调用Dispatcher.BeginInvoke。等等......这就是等待“让你回到原来的位置。”
使用未更改的SychronizationContext(例如使用控制台应用程序),continuation将排队到ThreadPool,因此它可以在任何线程上运行。