Wonder if this might be a good place to use a context manager.

The scoping/threads/event loop here may make that kind of weird though.

Maybe make WidgetUpdate a context manager, then instead of passing the WidgetUpdate to
AsyncWidgetUpdater, pass the widget, and create the WidgetUpdate in the .update()?

(untested psuedo code...)

```
class WidgetUpdate(object)
... <make context managery> 
   def __exit__(self, type, value, traceback):
        gobject.idle_add(self.finished)

class AsyncWidgetUpdate(object):
     <...>
    def worker(self,  backend_method, args=[], kwargs={}, exception_msg=None, callback=None):
        try:
            result = backend_method(*args, **kwargs)
            if callback:
                gobject.idle_add(callback, result)
        except Exception, e:
            message = exception_msg or str(e)
            gobject.idle_add(handle_gui_exception, e, message, self.parent_window)

    def update(widget, backend_method, args=[], kwargs={}, exception_msg=None, callback=None):
       with WidgetUpdate(widget):
            threading.Thread(target=self.worker, args=(backend_method, args, kwargs, exception_msg, callback)).start()
```

Not sure that's any cleaner for this particular case, but the idea of something like

(more totally untested psuedocode)

```
class GuiThreadThing(object):
   def __init__(self):
      # ref to a main loop timeout to catch misc threads?

      # ref to shared locking?

    def __enter__(self):
       # start timeout clock?
       # get lock?
       # set widget insensitive or otherwise ignore/coalesce events 

        do_some_thing_that_spins_off_a_thead()

   def __exit__(...):
       # unset timeout
       # release lock
       # add any callbacks to the idle loop with the result
       # potentially swallow exceptions...
       # or add handlers to idle loop

    with GuiThreadThing():
          do_thread_voodoo()

```