繁体   English   中英

WebClient在哪个线程上引发事件?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM