-1

Short version: How do I pump for messages while at a particular stack frame so I can wait for a custom dialog to return while blocking, just like Window.ShowDialog(). Ideally avoiding async or multiple threads.

I am creating a custom Notification Dialog for my application which supports a set of different display modes.

It can be used as a blocking popup, exactly like MessageBox.Show, by using Window.ShowDialog(). It can also act as a non-blocking message box by using the regular Show command.

However, I want to have third mode, where the dialog can be shown with a non-blocking call, but then later another call will block until the user closes the dialog. This is so I can let the user know earlier on when they will need to do something, but when the time comes, if the user hasn't already dismissed it the main application thread will block.

Keep in mind I’m not using Async with this.

Basically: NotifyDialog.ShowNonBlocking(“please remove the device and click OK.”); //do stuff, wait for processing to complete.

//processing now done, we really need to get rid if the device before the next thing starts. NotifyDialog.BlockUntilClosed(); //disables main window, starts nested message pump here.

I first wrongly assumed that creating a new Window would create a new thread and Dispatcher queue automatically, so I tried using a condition. Turns out that it doesn't create a new thread. I assumed this because Window.ShowDialog() blocked while the new dialog was shown, but as far as I can tell now it just disables all other windows, and kind of hijacks the message pump (I assume that the stack would look something like main -> message pump -> event that lead us to the ShowDialog() call -> new, hijacked message pump loop.)

Anyway, I would like to reproduce this behavior manually so in my NotifyDialog.BlockUntilClosed() call I can hijack the message pump, disable my main window, and wait for the window to close.

If this isn't possible, I’m going back to the plan of launching the window on a new thread, which there seems to be a handful of articles explaining.

I want to keep this easy to use, so I don't want to depend on closed event callbacks that the consumer would need to use, and my application isn't using Async right now, so I can't await the result.

Marcus10110
  • 509
  • 4
  • 12
  • It doesn't look like you are actually asking a specific question, rather it looks like you are requesting somebody give you some code that does what you described. Therefore this is currently not a good fit for stackoverflow's question and answer format. – Zack May 04 '15 at 21:58
  • Thanks John. It looks like the answer to my question lies in the DispatcherFrame class; should be able to get this figured out shortly. – Marcus10110 May 04 '15 at 21:58
  • 1
    Hmya, ShowDialog() is one of those highly unappreciated method calls that covers an enormous surface area. The problem with re-entrancy is notoriously poorly understood. You invoke the perils of DoEvents at your own risk, [read this](http://stackoverflow.com/a/5183623/17034) for background info. – Hans Passant May 04 '15 at 22:04
  • Hi Zack, thanks for the feedback. I think my question of is it possible to do X with the dispatcher is a clear question. X is clearly defined, specific, and limited in scope. I've gone out of my way to exclude alternative solutions. – Marcus10110 May 04 '15 at 22:07

1 Answers1

0

Alright, figured it out.

The dispatcher has a method called PushFrame. This function is a simple event loop. It's a while loop that won't return until the continue flag on the passed in DispatcherFrame is set to false, at which point it stops processing events and returns.

The solution was to add a member Dispatcher frame to my class, and construct it and pass it to the Dispatcher with the PushFrame call when the BlockUntilClosed method was called. Then, in my Close event handler for the dialog, I set the continue flag to false. Once the Dispatcher finished processing the close event, it detects that the continue flag has been cleared and returns.

There is a fairly good description here:

DispatcherFrame. Look in-Depth

Marcus10110
  • 509
  • 4
  • 12