1

I assume that I can just call

var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(Action());
dispatcherOp.Completed += dispatcherOp_Completed;

but then I am a little concerned. If begininvoke is asynchronous, then What prevents the dispatcher from completing the action before I get the returned dispatcher operation and attach to the completed event.

i assume that this must be impossible, but if so, I would like to know why.

James Joshua Street
  • 3,259
  • 10
  • 42
  • 80

4 Answers4

3

You are correct; this is not safe. You should simply await the operation.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

The answer is: nothing.

There are three possible approaches:

1.) You can decide that it is not important to wait for the operation to be executed. If so, then you are choosing the fire and forget strategy.

2.) You can decide that you want a synchronous request, so you await, like SLaks suggested.

3.) You can keep the request to be asynchronous, but use a callback.

Community
  • 1
  • 1
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

Unfortunately Dispatcher does not have a callback function it takes for begininvoke.

Synchronous operation is not desired in my program, but I realized after a google search or two that I can lock on it like this

lock (this)
            {
                var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(MyAction, DispatcherPriority.Normal);
                dispatcherOp.Completed += dispatcherOp_Completed;
            }



void dispatcherOp_Completed(object sender, EventArgs e)
        {
            lock (this)
            {

            }

        }

and then lock again on the same object in the completed function so that the dispatcher can't complete till you have finished attaching your handler.

James Joshua Street
  • 3,259
  • 10
  • 42
  • 80
0

There is never a reason to use Dispatcher.BeginInvoke in a modern application.

If your code models a background operation, then use async/await, with IProgress<T> for any progress updates.

If your code models an asynchronous sequence, then use Rx (Reactive Extensions) with ObserveOn to update objects with UI thread affinity.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • is there a way to use async await to call stuff on the GUI thread? – James Joshua Street May 29 '15 at 17:36
  • I've always found that it's better to reverse that logic: the GUI thread drives everything in the app. Nothing ever calls the GUI thread. Background ops can report results (which the GUI thread retrieves with `await`), updates (`IProgress`), or events (Rx), but they never actually call the GUI thread directly. – Stephen Cleary May 29 '15 at 17:56
  • ok read some examples and i think i understand it better. reading about reactive extensions now. never heard of it before – James Joshua Street May 29 '15 at 19:29