views:

881

answers:

4

Is there any way to process all Windows messages while the UI thread is waiting on a WaitHandle or other threading primitive?

I realize that it could create very messy reentrancy problems; I want to do it anyway.

EDIT: The wait occurs in the middle of a complicated function that must run on the UI thread. Therefore, moving the wait to a background thread is not an option. (Splitting the function in two would make a complicated and unmaintainable mess)

+3  A: 

Why wouldn't you just spawn another thread to do the waiting and have him notify the UI thread via message (or whatever) at the appropriate juncture?

That's the usual approach to allow for UI thread message handling during a blocking event.

EDIT: I see now -- you have that app logic logic built into the UI code. Well, this is really a design issue then. You're better off in the long-run breaking that functionality out from the UI into a self-contained object and using some mechanism to communicate status with the UI from your worker.

Aside from the benefit of keeping your UI code focused on UI, this allows you to unit-test the logic code separately.

DarkSquid
+1, waiting on the UI thread is not cool. Use a callback.
Joel Coehoorn
Because I'm waiting in the middle of a function that must run on the UI thread (non-thread-safe data objects bound to UI), and I don't want to have to split it and save the local variables.
SLaks
It's not UI logic - it's a data object that can only be read from the UI thread.
SLaks
+1  A: 

Not sure about C#, but in plain Win32 programming, you can use one of the MsgWaitFor...() functions for the actual waiting. It will notify you when messages are present in the message queue, as well as when the object(s) being waited on become signaled. If it reports a message is present, you can call GetMessage(), TranslateMessage(), and DispatchMessage() to process a message, and then go back to waiting.

Remy Lebeau - TeamB
+2  A: 

I'd normally recommend putting your wait condition on another thread.

However, that being said, you can always call Application.DoEvents to process the message pump at any point, including while "waiting" on a wait handle (just timeout, do events, wait with timeout, etc, until you get "through" the waithandle).

Reed Copsey
+3  A: 

I'd run the whole "Complicated-function-that-can-not-be-split" in a separate background thread, and have it to report to the GUI only when it needs to (using Invoke/BeginInvoke methods on a control).

In a more enhanced version, you should run your complicated function in a non-UI controller that does not depend on the UI, and is easier to unit test. Calling back to the UI and showing the result in the UI, can easily be reached by having the UI to subrscribe to events made available by the controller.

taoufik