interest in DelayedResult?

This is now easier to use, IMO. Feedback welcome.
Oliver

DelayedResult.py (5.68 KB)

···

-----Original Message-----
From: Oliver Schoenborn [mailto:oliver.schoenborn@greenley.ca]
Sent: August 3, 2006 9:57 AM
To: wxPython-users@lists.wxwidgets.org
Subject: [wxPython-users] interest in DelayedResult?

I have created a module called DelayedResult.py (still prototype, but
works) that helps use multithread in GUI apps, something many
novice users are not comfortable with. It's basic use case is:

- you have a task, triggered by a GUI event, that takes more than
  1/10th sec to execute, so you loose GUI response in that time
- starting the task from the event handler actually involves going
  through one or more layers with pre-processing at each level; e.g.
  handler calls slowTask, which does some setup stuff then itself
  calls lowerLevelSlowTask, which starts the thread and
returns immediately
- when the task is done, the result is new data that must be
pushed to the GUI
- once the result is available, each (or at least one) level needs to
  do some post-processing before the final result can be sent to GUI

DelayedResult makes it really easy to get the final result
back from the thread to the GUI, without having to know
anything about creating new event types or CallAfter etc. It
manages the reverse chain of "callers", makes it a lot easier
to transform a single thread impl to a multi-thread
implementation, and makes it easy to see what is pre- and
post-processing of the slow task. It also limits the amount
of synchronization code needed. You need WxAppTester.py to
run the module test.

Example (pseudo code):

# Single threaded case:

handle_download(self, event):
   # get file from web server:
   fileObj = serverProxy.get_file( theFile ) # blocks/takes long
   ask_user_where_to_save() # post-processing
   update_tree_view()

class ServerProxy:
   ...
   get_file(self, theFile):
       ... pre-processing, e.g. add complete path to theFile ...
       fileObj = NetServices.get_file( theFilePath ) #
blocks/takes long
       ... post-processing using fileObj ...
       return fileObj

class NetServices:
    get_file(self, filePath):
       ... pre-processing ...
       ... use urlopen etc... blocks here until got it ...
       return fileObj

# Transform for two threaded case using DelayedResult. Note
how # the structure is the same but post- stuff are now split
into # separate functions:

class YourController:
    handle_download(self, event):
        # get file from web server:
        delayedResult = DelayedResult( self.__haveNewResult )
        # now returns "immediately" with nothing:
        serverProxy.get_file( theFile, delayedResult )

    __haveNewResult(self, delayedResult):
        fileObj = delayedResult.getResult()
        ask_user_where_to_save() # post-processing
        update_tree_view()

class ServerProxy:
    ...
    get_file(self, theFile, delayedResult):
        ... pre-processing, e.g. add complete path to theFile ...
        delayedResult.prepend( self.__haveNewResult )
        # now returns "immediately" with nothing:
        NetServices.get_file( theFilePath, delayedResult )

    __haveNewResult(self, delayedResult):
        something = delayedResult.getResult()
        ... post-processing using something ...
        return fileObj

class NetServices:
    ...
    get_file(self, filePath, delayedResult):
        ... pre-processing ...
        def threadedFn(delayedResult):
            fileObj = urlopen(...) # blocks/takes long
            delayedResult.sendResult(fileObj)
        thread.start_new(threadedFn, (delayedResult,))

Would it make sense to have it in wx.lib?

Oliver

Oliver Schoenborn wrote:

This is now easier to use, IMO. Feedback welcome.

The eventType parameter in DelayedResult.ByEvent should be named eventBinder or something similar. (eventType is the name used for the numeric event IDs.)

Would it make sense to allow appending of listeners instead of just prepending?

The ByClass and ByEvent names aren't very intuitive for what they do, but I'm not able to think of anything else at the moment to suggest...

I'd like to see a good informative module docstring before adding it to wx.lib.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!