in reply to Keeping a Win32::GUI interface responsive while executing other code?

I've recently been working on exactly the same kind of problem with my own programming project; that of how to best keep a GUI responsive, while at the same time handling LWP requests.  I can tell you what has worked very nicely for me, and let you evaluate whether it's a solution you wish to pursue or not.

The basic strategy is to have two separate threads, a parent thread and a child thread.

The parent thread handles all of the GUI interactions, and anything else which is reasonably "lightweight".  The child thread handles all of the LWP (ie. downloads from a webserver), and otherwise just sits and spins in a tight loop.  I use threads::shared to share a few essential data between the threads, including some "state " variables, and I use Thread::Queue to pass a variable number of items back from the child to the parent.

Pictorially, here is a diagram of how the threads interact, given a variable "$state_var":

Parent Child +----------+ +-------------------------+ +----------------------- +-+ |Start: | |Decides remote data is | |Detects value of 1; + | |$state_var|==>|needed; parent changes |==>|Attempts to fetch the + | |value = 0 | |the value from 0 to 1. | |data using LWP. + | +----------+ +-------------------------+ | + | ^ +-------------------------+ |Success: Child changes + | | |Detects the value of 2; | |the value from 1 to 2, + | | |Reads the shared queue to| |and writes the data bac +k| +===========|retrieve the data, change|<==|to the shared queue. + | | |the value from 2 to 0, | | + | | |and return to Start. | |Failure: Child changes + | | +-------------------------+ |the value from 1 back t +o| | |0 to indicate failure, + | +=========================================|and returns to Start. + | +----------------------- +-+

This has proven very successful for me; the parent is the only thread which can change the state variable from 0 to 1; the child is the only thread which can change it from 1 to 0 (on an error), or from 1 to 2 (on success), and the parent is the only thread which can change it from 2 back to 0 (and at the same time, retrieve any data the child thread is writing).

Prior to my implementing threads, the GUI was very non-responsive for often as many as 10-20 seconds at a time, if there was, for any reason, a delay in the remote data fetch.  Now, the GUI has no problems interacting; when data is delayed, it simply continues to wait until the state variable changes to indicate that it was successful, and that data is waiting to be fetched from the child (which, of course, happens very quickly).

I've run the program so far under Windows XP and Linux, with equal success.  I would be interesting to hear whether similar success is possible under Windows 2000 (or other platforms), but I don't see any reason why it shouldn't be, as long as the version of ActiveState Perl was the most recent available.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
  • Comment on Re: Keeping a Win32::GUI interface responsive while executing other code?
  • Download Code