If I read your comments correctly, you call Dispatcher.CurrentDispatcher from a thread other than the UI. This does not mean that it is intended to be used.
As the documentation for Dispatcher.CurrentDispatcher says:
Gets the dispatcher for the current thread and creates a new dispatcher, if not already associated with the stream .
To get a valid dispatcher instance, you need to call Dispatcher.CurrentDispatcher from the user interface thread.
In addition, since the documentation says that it will automatically create a dispatcher if it does not exist for the current thread, this explains the silent failure. You get a dispatcher instance, but it is in no way associated with the user interface thread, so it does not actually send anything to the user interface thread.
(Removing this because in my tests I get null, even if I shouldn't, so it doesn't seem that much. The rest of the information is accurate, though) The documentation also added:
This does not apply to the FromThread method. FromThread will return null if the dispatcher is not associated with the specified thread.
So, to confirm that you are really getting an auto-created (invalid) dispatcher, try sending the dispatcher from Dispatcher.FromThread instead. I assume you get null .
If you want to call dispatcher.BeginInvoke to force the method to execute on the user interface thread from the workflow, you need to call Dispatcher.CurrentDispatcher from the user interface thread and save it in a variable. You can then pass this dispatcher reference variable to the workflow and call BeginInvoke .
// capture and save dispatcher from UI thread Dispatcher dispatcher = Dispatcher.CurrentDispatcher; // then you can do this from your worker thread: dispatcher.BeginInvoke(theMethod);
Alternatively, use this.BeginInvoke , as you already do.
Or even better, you can try using tasks in conjunction with the new async-await keywords for this kind of thing.
EDIT
For completeness, I must explain why Control.BeginInvoke working correctly.
The Control.BeginInvoke documentation says:
Runs the specified delegate asynchronously in the thread on which the control base descriptor was created.
And later he also adds:
You can call this method from any thread.
The fact is that when calling Control.BeginInvoke it does not use the current thread to determine how to execute the delegate. It remembers which thread the control was created (user interface thread), and ensures that the delegate runs on that thread.
So, while your control is being created in the user interface thread (as it should be), then BeginInvoke works from any thread. This is actually very similar to Dispatcher in that as long as you first get a Dispatcher instance from the UI thread, then you can call dispatcher.BeginInvoke from any stream.