[英]On which thread(s) does WebClient raise its events?
我找不到任何指定WebClient在哪个线程上引发事件的文档。 我进行了一些测试,并确定了以下内容:
如果从UI线程(例如从事件处理程序)调用,则事件处理程序将在该线程上执行。 作为测试,我在调用OpenReadAsync之后添加了一个无限循环。 从未调用过事件处理程序。
如果没有UI线程(例如在控制台应用程序中),则事件处理程序将在线程池线程上执行。 在这种情况下,如果我想在应用程序的其余部分提供一些结果,则必须注意线程问题。
此行为记录在任何地方吗? 我什么都没找到。
关于C#的新异步功能,我有基本相同的问题-最终,必须执行异步代码。 当没有UI线程时,是否还会生成线程池线程? 进而需要线程安全代码吗?
我觉得我在这里错过了一些东西-我只能找到很少的信息,但这对我来说似乎很重要。
对于WebClient
,我也没有找到任何文档,但是看到的行为与您相同。 本质上,这可以描述为“如果调用开始时有活动的同步上下文,则使用它-否则使用线程池。”
对于C#5中的异步行为,它取决于您正在等待的内容的实现...但是我相信Task<T>
等待者将使用TaskScheduler.Current
来安排继续时间-这意味着您将看到相同的内容某种行为。 (不一定是设置任务计划程序的UI线程,但这是最明显的示例。)
使用线程池线程时,它仍应是线程安全的-该方法一次仅在单个线程中执行,我相信任务并行库会执行所有必需的内存屏障。
如果您对异步如何在后台挂在一起感兴趣,您可能需要阅读我的Eduasync博客系列 。
WebClient类实现基于事件的异步模式 。 该模式已在《框架设计指南》中进行了充分描述,但MSDN还提供了一些如何实现的提示:
该模式的实现者使用AsyncOperationManager创建AsyncOperation使用每个异步操作并引发事件AsyncOperation.Post方法 。 该POST方法执行的传递回调的SynchronizationContext ,这是当前在当时的时候AsyncOperation创建。
WinForms或WPF应用程序中的默认SynchronizationContext是UI线程,在控制台应用程序中为null
。 WebClient类显然选择在后一种情况下在ThreadPool线程中引发事件,但这是实现细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.