C# 异步回调在哪个线程上运行?

C# 异步回调在哪个线程上运行?,c#,multithreading,asynchronous,httpwebrequest,C#,Multithreading,Asynchronous,Httpwebrequest,我正在进行几个HttpWebRequest.BeginGetResponse调用,在BeginGetResponse的回调方法中,我正在调用一个EventHandler。在EventHandler中,有逻辑测试下载是否成功。如果没有,它将尝试重新下载Html。我注意到有很多线程被生成,特别是当出现错误时。那么,异步回调在哪个线程上运行 我是否可以在原始线程上调用EventHandler?如果不可能,我可以在UI线程上调用它吗 谢谢 如果您使用的是WPF,那么可以使用Dispatcher在UI线程

我正在进行几个
HttpWebRequest.BeginGetResponse
调用,在
BeginGetResponse
的回调方法中,我正在调用一个EventHandler。在EventHandler中,有逻辑测试下载是否成功。如果没有,它将尝试重新下载Html。我注意到有很多线程被生成,特别是当出现错误时。那么,异步回调在哪个线程上运行

我是否可以在原始线程上调用EventHandler?如果不可能,我可以在UI线程上调用它吗


谢谢

如果您使用的是WPF,那么可以使用Dispatcher在UI线程上调用您的逻辑


否则,(如果不在WPF中)您可以使用SyncrhonizationContext来完成相同的任务。

如果您使用WPF,则可以使用Dispatcher来调用UI线程上的逻辑

否则,(如果不是在WPF中)您可以使用SyncrhonizationContext来完成同样的事情。

您所说的“在原始线程上”是什么意思?哪一个原始线程?您可以使用
Control.BeginInvoke
Dispatcher.BeginInvoke
封送到UI线程。您不能封送到任意线程-它必须有消息泵之类的东西等待工作

至于在哪个线程上执行
HttpWebRequest
异步回调-我希望是一个普通线程池工作线程,或者可能是一个IO完成端口线程。

您所说的“在原始线程上”是什么意思?哪一个原始线程?您可以使用
Control.BeginInvoke
Dispatcher.BeginInvoke
封送到UI线程。您不能封送到任意线程-它必须有消息泵之类的东西等待工作


至于在哪个线程上执行
HttpWebRequest
异步回调,我希望是普通线程池工作线程,或者可能是IO完成端口线程。

回调是在线程池线程上执行的。NET中没有使代码在特定线程上运行的机制。这很难做到,你不能在线程忙的时候中断它,让它运行一些代码。这会导致可怕的重入问题,而锁无法解决这些问题

线程必须处于空闲状态,而不是主动改变程序的状态。有一种线程就是这样运行的,Winforms或WPF应用程序中的UI线程。这也是必须处理从根本上说是线程不安全的对象的线程,任何与UI相关的对象。这不是巧合


这两个类库都可以封送从工作线程到UI线程的调用,特别是帮助以线程安全的方式更新UI。在Winforms中使用Control.Begin/Invoke(),在WPF中使用Dispatcher.Begin/Invoke()。BackgroundWorker是一个方便的类,无需显式管理封送即可完成此操作。但不适用于I/O完成回调。

回调是在线程池线程上进行的。NET中没有使代码在特定线程上运行的机制。这很难做到,你不能在线程忙的时候中断它,让它运行一些代码。这会导致可怕的重入问题,而锁无法解决这些问题

线程必须处于空闲状态,而不是主动改变程序的状态。有一种线程就是这样运行的,Winforms或WPF应用程序中的UI线程。这也是必须处理从根本上说是线程不安全的对象的线程,任何与UI相关的对象。这不是巧合


这两个类库都可以封送从工作线程到UI线程的调用,特别是帮助以线程安全的方式更新UI。在Winforms中使用Control.Begin/Invoke(),在WPF中使用Dispatcher.Begin/Invoke()。BackgroundWorker是一个方便的类,无需显式管理封送即可完成此操作。但不适用于I/O完成回调。

使用开始/结束异步模式,请注意许多类型的任务都可以在调用它们的线程上完成。调用BeginXXX时,它返回一个布尔值,表示任务是否在调用线程上完成


基本答案是,它可以是任何线程。

使用Begin/End异步模式,请注意许多类型的任务都可以在调用它们的线程上完成。调用BeginXXX时,它返回一个布尔值,表示任务是否在调用线程上完成


基本答案是,它可以是任何线程。

“在原始线程上”是调用
HttpWebRequest.BeginGetResponse
的线程。因此,例如,如果UI生成一个线程a,a调用HttpWebRequest.BeginGetResponse(正如您所说,将一个新线程放入线程池。我们将其称为线程B),然后调用EventHandler,我希望它在线程a或UI线程上运行。但是从我观察到它在线程B上运行。然后,如果有错误,线程B调用
HttpWebRequest.BeginGetResponse
,然后创建线程C,依此类推。。。希望helps@joe_coolish:为什么它会在线程A上运行,而您为什么会在意?如果线程A仍在执行其他代码,您希望发生什么?我完全不知道你所说的“在线程池中放置一个新线程”是什么意思。。。或者线程B为什么再次调用BeginGetResponse。。。这在你自己的代码中吗?当然,线程池会在可能的情况下重用线程。我之所以关心这个问题,是因为线程池太大了,所以我会收到OOME。我的代码(我相信这才是真正的问题所在)有两种方法。1接受URL和EventHandler回调。它创建HttpWebRequest对象并调用BeginGetResponse。方法2是AsyncCallback,如果调用出错,它将通过URL和t调用方法1