You got it.
···
-----Original Message-----
From: Robin Dunn [mailto:robin@alldunn.com]
Sent: Wednesday, January 09, 2008 5:17 PMGive me a good explanatory sample to put into the demo and I'll add it.
You got it.
-----Original Message-----
From: Robin Dunn [mailto:robin@alldunn.com]
Sent: Wednesday, January 09, 2008 5:17 PMGive me a good explanatory sample to put into the demo and I'll add it.
Here's a splash. Perky li'l. Attached & reproduced.
Here's the catch. AsyncCall may deadlock with CallAfter. Current solution
permits 'timeout' and 'failval' arguments. Specifically, in line 56,
AsyncCall().Wait() times out in one second. I observed it three times BTOP
by time of posting, by setting line 69 and holding down Alt-F4, FTA, for the
archives.
Versions MSW XP- Python 2.5.1- wxWidgets 2.8.6.1.
Thanks.
from __future__ import with_statement
import wx
import time
import threading
class AsyncCall:
from threading import Event
''' Queues a func to run in thread of MainLoop.
Code may wait() on self.complete for self.result to contain
the result of func(*ar,**kwar). It is set upon completion.
Wait() does this.'''
def __init__( self, func, *ar, **kwar ):
self.noresult= object()
self.result, self.complete= self.noresult, self.Event()
self.func, self.ar, self.kwar= func, ar, kwar
wx.CallAfter( self.TimeToRun )
def TimeToRun( self ):
self.result=self.func( *self.ar, **self.kwar )
self.complete.set()
def Wait( self, timeout= None, failval= None ):
self.complete.wait( timeout )
if self.result is self.noresult:
return failval
return self.result
class ThreadEx( threading.Thread ):
def __init__( self, func ):
threading.Thread.__init__( self, target= func, args= ( self, ) )
self.bContinue, self.finishlock= True, threading.Lock()
self.start()
def BindEx( control, event ):
def pre( func ):
control.Bind( event, func )
return func
return pre
if __name__== '__main__':
def main():
app= wx.PySimpleApp()
frame= wx.Frame( None, title= "AsyncCall Demo" )
sizer= wx.BoxSizer( wx.VERTICAL )
text1= wx.TextCtrl( frame, value= "Change this." )
sizer.Add( text1, 1, wx.EXPAND )
gauge1= wx.Gauge( frame )
sizer.Add( gauge1, 0, wx.ALIGN_CENTER )
frame.SetSizer( sizer )
frame.Show()
@ThreadEx
def thr1( thr1 ):
while 1:
with thr1.finishlock:
if not thr1.bContinue: break
AsyncCall( gauge1.Pulse ) #do not Wait
caption= AsyncCall( text1.GetValue ).Wait( 1 )
print 'Text: %s\n'% caption,
time.sleep( .1 )
@BindEx( frame, wx.EVT_CLOSE )
def onclose( event ):
thr1.bContinue= False
with thr1.finishlock: pass
event.Skip()
app.MainLoop()
thr1.join()
if 1:
main()
else: #try the line-56 None deadlock timeout return
while 1:
main()
asyncable.py (2.25 KB)
-----Original Message-----
From: Aaron Brady [mailto:castironpi@comcast.net]
Sent: Wednesday, January 09, 2008 5:21 PM> -----Original Message-----
> From: Robin Dunn [mailto:robin@alldunn.com]
> Sent: Wednesday, January 09, 2008 5:17 PM
>
> Give me a good explanatory sample to put into the demo and I'll add it.You got it.