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?
You can call methods asynchronously in four different ways using the BeginInvoke() and EndInvoke() methods of the Delegate class. The four different ways are using the EndInvoke pattern, WaitHandle, Polling pattern and using a Callback Pattern. In this article, we will see the Delegate EndInvoke Pattern.
BeginInvoke returns an IAsyncResult, which can be used to monitor the progress of the asynchronous call. The EndInvoke method retrieves the results of the asynchronous call. It can be called any time after BeginInvoke . If the asynchronous call has not completed, EndInvoke blocks the calling thread until it completes.
The AsyncCallback delegate represents a callback method that is called when the asynchronous operation completes. The callback method takes an IAsyncResult parameter, which is subsequently used to obtain the results of the asynchronous operation.
The IAsyncResult interface is implemented by classes containing methods that can operate asynchronously. It is the return type of methods that initiate an asynchronous operation, such as FileStream. BeginRead, and it is passed to methods that conclude an asynchronous operation, such as FileStream. EndRead.
On 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
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...
};
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With