def show_threadsafe(cls, *args): ''' A threadsafe method for instantiating a new ComicForm on a NEW Application thread, and then displaying it to the user. The Application thread will shutdown and dispose automatically when the ComicForm is closed. All given arguments will be passed to the new ComicForm's constructor. ''' cls.newform = None def shower(): with cls(*args) as form: Monitor.Enter(cls) try: cls.newform = form Monitor.Pulse(cls) finally: Monitor.Exit(cls) def exception_handler(sender, event): log.handle_error(event.Exception) Application.ThreadException +=\ ThreadExceptionEventHandler(exception_handler) Application.Run(form) # start form on new App thread; blocks Monitor.Enter(cls) try: # starts a new thread, which will become the Application thread/ event # pump for the newly created ComicForm, Thread(ThreadStart(shower)).Start() Monitor.Wait(cls) finally: Monitor.Exit(cls) newform = cls.newform del cls.newform # make sure this method does not return until the newly created ComicForm # has actually been made visible and active. see bug 139. def activate_form(): # this call is probably not needed; the real trick here is that # invoking this method synchronously delays us until the form has # a nice, visible handle on-screen newform.Activate() utils.invoke(newform, activate_form, True) return newform
def threadloop(): task = None while task != self: try: Monitor.Enter(self) try: task = self.task if task != self: self.task = None if task is None: Monitor.Wait(self) finally: Monitor.Exit(self) if task != self and task is not None: task() except Exception as ex: # slightly odd error handling, cause this thread should NEVER # die as the result of an exception! try: log.handle_error(ex) except: pass task = None