简体   繁体   English

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

[英]On which thread do Async Callbacks run?

I'm making several HttpWebRequest.BeginGetResponse calls, and in the callback method of the BeginGetResponse , I'm invoking an EventHandler. 我正在进行几个HttpWebRequest.BeginGetResponse调用,并且在BeginGetResponse的回调方法中,我正在调用EventHandler。 In the EventHandler, there is logic to test if the download was successful. 在EventHandler中,有逻辑可以测试下载是否成功。 If not, it tries to redownload the Html. 如果不是,它将尝试重新下载HTML。 I'm noticing lots of threads being generated especially when there are errors. 我注意到正在生成大量线程,尤其是在出现错误时。 So, on which thread do the Async Callbacks run? 那么,异步回调在哪个线程上运行?

Is there anyway I can invoke the EventHandler on the original thread? 无论如何,我可以在原始线程上调用EventHandler吗? If that is not posible, can I invoke it on the UI thread? 如果那不可能,我可以在UI线程上调用它吗?

Thanks! 谢谢!

What do you mean by "on the original thread"? “在原始线程上”是什么意思? Which original thread? 哪个原始线程? You can marshal to the UI thread using Control.BeginInvoke or Dispatcher.BeginInvoke . 您可以使用Control.BeginInvokeDispatcher.BeginInvoke编组到UI线程。 You can't marshal to an arbitrary thread - it has to have something like a message pump waiting for work. 你不能元帅任意线程-它必须有类似的消息泵等待工作。

As for which thread HttpWebRequest async callbacks are executed on - I would expect either a general thread pool worker thread, or possibly an IO completion port thread. 至于在哪个线程上执行HttpWebRequest异步回调-我希望可以是通用线程池工作线程,也可以是IO完成端口线程。

Callbacks are made on a threadpool thread. 回调是在线程池线程上进行的。 There is no mechanism in .NET to make code run on a specific thread. .NET中没有机制可以使代码在特定线程上运行。 That is very hard to come by, you can't just interrupt a thread while it is busy and make it run some code. 这很难实现,您不能只在线程繁忙时中断它并使其运行一些代码。 That causes horrible re-entrancy problems that a lock cannot solve. 这会导致锁无法解决的可怕的重新进入问题。

A thread must be in an idle state, not actively mutating the state of the program. 线程必须处于空闲状态,不能主动改变程序的状态。 There's one kind of thread that behaves that way, the UI thread in a Winforms or WPF app. WinForms或WPF应用程序中的UI线程就是这种行为的一种。 That's also the thread that has to deal with objects that are fundamentally thread-unsafe, anything related to the UI. 这也是必须处理基本上是线程不安全的对象(与UI相关的任何对象)的线程。 This is not a coincidence. 这不是巧合。

Both class libraries make it possible to marshal a call from a worker thread to the UI thread, specifically to help getting the UI updated in a thread-safe way. 这两个类库都可以封送从工作线程到UI线程的调用,特别是有助于以线程安全的方式更新UI。 In Winforms you use Control.Begin/Invoke(), in WPF you use Dispatcher.Begin/Invoke(). 在Winforms中,您使用Control.Begin / Invoke();在WPF中,您使用Dispatcher.Begin / Invoke()。 BackgroundWorker is a handy class to get this done without explicitly managing the marshaling. BackgroundWorker是一个方便的类,可以在不显式管理封送处理的情况下完成此任务。 But isn't suitable for I/O completion callbacks. 但不适用于I / O完成回调。

Using the Begin/End Async pattern, be aware that it's possible for many kinds of tasks to complete on the thread they were called from. 请注意,使用“开始/结束异步”模式可以使许多任务在调用它们的线程上完成。 When you call BeginXXX, it returns a boolean that signifies if the task was completed on the calling thread or not. 当您调用BeginXXX时,它将返回一个布尔值,该布尔值表示任务是否在调用线程上完成。

The basic answer is, it could be any thread. 基本的答案是,它可以是任何线程。

If you are using WPF you can use the Dispatcher to invoke your logic on the UI thread. 如果使用WPF,则可以使用Dispatcher在UI线程上调用逻辑。

Otherwise, (if not in WPF) you could use a SyncrhronizationContext to accomplish the same thing. 否则,(如果不在WPF中)您可以使用SyncrhronizationContext完成相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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