Add support for aborting the worker thread

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41354 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-09-21 19:14:02 +00:00
parent dd267523d0
commit 45c0ea45ff
2 changed files with 54 additions and 22 deletions

View File

@@ -56,7 +56,8 @@ class FrameSimpleDelayed(FrameSimpleDelayedBase):
def __init__(self, *args, **kwargs):
FrameSimpleDelayedBase.__init__(self, *args, **kwargs)
self.jobID = 1
self.jobID = 0
self.abortEvent = delayedresult.AbortEvent()
self.Bind(wx.EVT_CLOSE, self.handleClose)
def setLog(self, log):
@@ -67,54 +68,50 @@ class FrameSimpleDelayed(FrameSimpleDelayedBase):
app, so worker thread continues and sends result to dead frame; normally
your app would exit so this would not happen."""
if self.buttonAbort.IsEnabled():
self.Hide()
wx.FutureCall(5000, self.Destroy)
else:
self.Destroy()
self.log( "Exiting: Aborting job %s" % self.jobID )
self.abortEvent.set()
self.Destroy()
def handleGet(self, event):
"""Compute result in separate thread, doesn't affect GUI response."""
self.buttonGet.Enable(False)
self.buttonAbort.Enable(True)
self.abortEvent.clear()
self.jobID += 1
self.log( "Starting job %s in producer thread: GUI remains responsive"
% self.jobID )
delayedresult.startWorker(self._resultConsumer, self._resultProducer,
wargs=(self.jobID,), jobID=self.jobID)
wargs=(self.jobID,self.abortEvent), jobID=self.jobID)
def _resultProducer(self, jobID):
def _resultProducer(self, jobID, abortEvent):
"""Pretend to be a complex worker function or something that takes
long time to run due to network access etc. GUI will freeze if this
method is not called in separate thread."""
import time
time.sleep(5)
count = 0
while not abortEvent() and count < 50:
time.sleep(0.1)
count += 1
return jobID
def handleAbort(self, event):
"""Abort actually just means 'ignore the result when it gets to
handler, it is no longer relevant'. We just increase the job ID,
this will let handler know that the result has been cancelled."""
"""Abort the result computation."""
self.log( "Aborting result for job %s" % self.jobID )
self.buttonGet.Enable(True)
self.buttonAbort.Enable(False)
self.jobID += 1
self.abortEvent.set()
def _resultConsumer(self, delayedResult):
# See if we still want the result for last job started
jobID = delayedResult.getJobID()
if jobID != self.jobID:
self.log( "Got obsolete result for job %s, ignored" % jobID )
return
# we do, get result:
assert jobID == self.jobID
try:
result = delayedResult.get()
except Exception, exc:
self.log( "Result for job %s raised exception: %s" % (jobID, exc) )
self.jobID += 1
return
# output result
@@ -124,7 +121,6 @@ class FrameSimpleDelayed(FrameSimpleDelayedBase):
# get ready for next job:
self.buttonGet.Enable(True)
self.buttonAbort.Enable(False)
self.jobID += 1
class FrameSimpleDirect(FrameSimpleDelayedBase):