简体   繁体   中英

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. In the EventHandler, there is logic to test if the download was successful. If not, it tries to redownload the 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? If that is not posible, can I invoke it on the UI thread?

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 . 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.

Callbacks are made on a threadpool thread. There is no mechanism in .NET to make code run on a specific thread. 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. That's also the thread that has to deal with objects that are fundamentally thread-unsafe, anything related to the 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. In Winforms you use Control.Begin/Invoke(), in WPF you use Dispatcher.Begin/Invoke(). BackgroundWorker is a handy class to get this done without explicitly managing the marshaling. But isn't suitable for I/O completion callbacks.

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.

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.

Otherwise, (if not in WPF) you could use a SyncrhronizationContext to accomplish the same thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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