background threads and keeping the UI painting

M

Marina Levit

I am trying to do some processing on a background thread while keeping the
UI painting. However, this is a generic server side call routine - and it
needs to block until the server side call completes. So the idea is, a
server side call begins, it gets spun off on another thread to keep the UI
painting - but, the code flow cannot return to the caller until the server
side call completes, because the caller expects the data.

The only way I could find to do this, was to open a modal dialog after
spinning off the new thread to do the server call. Then the callback would
close the dialog, causing the UI thread to once again begin processing. The
callback had also set the return data, so everything worked fine.

The only problem was that every time the dialog popped open (which had an
animated image to let the user know work was happening), it would activate,
then it would close and the main form would reactivate. One logical
operation sometimes involved several server side calls - and each would pop
open the dialog and then close, resulting in a lot of flashing as the main
form deactivated then reactivated.

The dialog was the only way I could find to block the main thread, and yet
keep the UI painting, and at the same time prevent the user from clicking
anywhere back on the original form and trying to do something while in the
midst of an operation (because the dialog was modal).

Any suggestions for how to implement this kind of thing? Telling the thread
to sleep or anything of that nature does not keep the UI painting - and I'm
thinking Applicaiton.DoEvents is going to allow the user to click anywhere
and mess with things, which isn't going to work either.
 
M

Marina Levit

The entire application would have to be disabled as really any user
interaction could invalidate things. If the task happened to be short, it
would also look like a different type of flashing to disable/enable it. I am
fairly certain that those in charge of the look of the app are not going to
go for that, though that is an option.
 
R

Rich

Can't you keep the dialogue open until all the transactions have completed?

Instead of creating a dialogue each time you kick off a thread, open a
dialogue which then handles all the transactions in one go?

--

Rich

http://www.badangling.com
....talking pollocks since 1996
 
M

Marina Levit

This is a generic server side calling piece. Thousands of call streams go
through it - in all diff combinations.

So a click handler might have:

run some code dealing with UI object
server call
run some code dealing with UI objects
server call
run some code dealing with UI objects

So, if the dialog is opened up front, and then the click handler as a whole
is run on a separate thread, then anything touching UI objects is going to
die because UI things have to run on the UI thread.

Otherwise, it is just the server calls that are run on a separate thread -
which then brings up the point of how to block while waiting for the async
server call and yet paint the UI.

Yes, I realize multiple server side calls may not be optimal - but sometimes
they are necessary, and it is just not predictable how code was written and
it can't all be redone.
 
R

Rich

Ah, understand.

IMHO Application.DoEvents should never be used, when you find yourself
reaching for it, it's a sign that something's wrong with the design.


You could try something along the following lines (apologies for the pseudo
code).


ServerThread.Start()
LOOP WHILE ServerThread.Busy()
MainWindow.Refresh()
MainThread.Sleep(100)
END WHILE

The call to refresh the main window will invalidate the windows client area
causing it to redraw, the sleep 100 let's the system breath a bit by only
checking for server thread completion every 100mS.

Not an ideal bit of code but might get you closer to a solution hopefully?

Another approach might be to intercept the events that flow to the main
window of the app and selectively deal with them when in 'Modal' mode. Your
server thread would set a flag to tell the app that thread processing in
going on (Modal mode), so ignore windows events at that time. When not in
'modal' the events would be processed as usual. This approach can cause more
problems than it solves but could be a way of getting you out of a spot.
Google for "Subclass WndProc .Net" without the quotes for examples of how to
intercept Windows messages.

--

Rich

http://www.badangling.com
....talking pollocks since 1996
 
M

Marina Levit

Thanks for the Refresh idea, I tried Invalidate, but that did not really
work. I think this is all going to end up being scrapped and I am going to
be told to just put in a wait cursor instead....

Thanks for all your input.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top