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

C# WebClient在哪个线程上引发其事件?,c#,asynchronous,webclient,C#,Asynchronous,Webclient,我找不到任何指定WebClient在哪个线程上引发其事件的文档。我进行了一些测试,确定了以下几点: 如果从UI线程调用(比如从事件处理程序调用),事件处理程序将在该线程上执行。作为测试,我在调用OpenReadAsync后添加了一个无限循环。从未调用事件处理程序 如果没有UI线程,比如在控制台应用程序中,事件处理程序将在线程池线程上执行。在这种情况下,如果我想为应用程序的其余部分提供一些结果,我必须注意线程问题 这种行为是否有记录在案?我什么也没找到 关于C#的新异步特性,我有一个基本相同的

我找不到任何指定WebClient在哪个线程上引发其事件的文档。我进行了一些测试,确定了以下几点:

  • 如果从UI线程调用(比如从事件处理程序调用),事件处理程序将在该线程上执行。作为测试,我在调用OpenReadAsync后添加了一个无限循环。从未调用事件处理程序

  • 如果没有UI线程,比如在控制台应用程序中,事件处理程序将在线程池线程上执行。在这种情况下,如果我想为应用程序的其余部分提供一些结果,我必须注意线程问题

这种行为是否有记录在案?我什么也没找到

关于C#的新异步特性,我有一个基本相同的问题——最终,异步代码将不得不执行。当没有UI线程时,这还会产生线程池线程吗?这反过来又需要线程安全代码吗


我觉得我在这里遗漏了一些东西——我只能找到很少的信息,但这对我来说似乎很重要。

对于
WebClient
,我也没有发现它有文档记录,但看到了与您相同的行为。本质上,这可以描述为“如果在调用启动时有一个活动的同步上下文,则使用它,否则使用线程池。”

对于C#5中的异步行为,它取决于您正在等待的内容的实现。。。但是我相信
任务的等待者将使用
来安排继续-这意味着您将看到类似的行为。(设置任务调度器的不仅仅是UI线程,这是最明显的例子。)

当使用线程池线程时,它仍然应该是线程安全的-该方法一次只在单个线程中执行,我相信任务并行库可以执行所有需要的内存屏障

如果您对异步如何在幕后结合感兴趣,您可能需要阅读我的。

实现。该模式在框架设计指南中有详细描述,但MSDN也提供了一些提示:

该模式的实现者使用为每个异步操作创建一个,并使用引发事件。在创建时对上执行传递的回调


WinForms或WPF应用程序中的默认值是UI线程,或控制台应用程序中的
null
。在后一种情况下,显然选择在线程池线程中引发事件,但这是一个实现细节。

+1良好链接。但是,我不同意线程行为是一个实现细节。这对于事件处理程序的作者来说是很重要的信息。+1我想我缺少的是,CLR中已经有很多关于线程和同步的基础设施,可以假设WebClient使用这些基础设施。EduaAsync的帖子很有趣。问得好!我刚刚在WebClient上遇到了同样的事情,当我得出与你相同的结论时,我就开始用谷歌搜索。