From my understanding of .NET, if I use a BackgroundWorker and have an event handler for RunWorkerCompleted, the event handler will run on the same thread in which RunWorkerAsync was called. If instead I use BeginInvoke on a delegate to run a method asynchronously, and pass an AsyncCallback parameter to BeginInvoke, is there any way I can specify that the callback runs on the same thread that called BeginInvoke -- or for that matter any arbitrary thread? From my understanding the callback runs on the next available thread from the thread pool. That's fine, but is there a way I can run code in an AsyncCallback on any thread I want? I do know you can use BeginInvoke on a form or control and make code within the callback run on the thread that created the UI element. But what about if I want to run code on a non-UI thread with no forms or controls?
views:
194answers:
4On the thread you want to use as the target for your async operation, the CurrentDispatcher Property is a System.Threading.Dispatcher object that can be used to force a callback to execute on that thread.
This is the base class that the Control class uses to implement BeginInvoke.
Questions have come up about using this with Windows forms. I don't think this will be a problem, although if you have a form, then form.BeginInvoke is a better choice. It appears that both the form and WPF use the same base class for handling invoke. http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx
The thread will always be a thread pool thread, and will never be a UI thread.
BTW, C# has no BackgroundWorker
class. .NET does.
I did a search and I ended up on Jon Skeet's site. It is very informative about how the threading works with asynchronous delegates and callbacks. I would highly recommend this read.
Delegate.BeginInvoke will always execute the delegate in the ThreadPool and the AsyncCallback is called on the same thread that executed the delegate.
Your only choice is to re-invoke the callback on your specific thread:
AsyncCallback = delegate (IAsyncResult ar)
{
wathever.BeginInvoke(delegate
{
// Do your stuff...
};
};