Skip to content

Instantly share code, notes, and snippets.

@JasonLG1979
Created August 13, 2016 18:57
Show Gist options
  • Save JasonLG1979/e3ab511a60b64f5cdaa0a643d3f3540f to your computer and use it in GitHub Desktop.
Save JasonLG1979/e3ab511a60b64f5cdaa0a643d3f3540f to your computer and use it in GitHub Desktop.
async function decorator
import threading
import traceback
from gi.repository import GLib
__all__ = ['async_function']
def _async_call(f, args, kwargs, on_done):
def run(data):
f, args, kwargs, on_done = data
error = None
result = None
try:
result = f(*args, **kwargs)
except Exception as e:
e.traceback = traceback.format_exc()
error = 'Unhandled exception in asyn call:\n{}'.format(e.traceback)
GLib.idle_add(lambda: on_done(result, error))
data = f, args, kwargs, on_done
thread = threading.Thread(target=run, args=(data,))
thread.daemon = True
thread.start()
def async_function(on_done=None):
'''
A decorator that can be used on free functions so they will always be called
asynchronously. The decorated function should not use any resources shared
by the main thread.
Example:
def do_async_stuff(self, input_string):
def on_async_done(result, error):
# Do stuff with the result and handle errors in the main thread.
if error:
print(error)
elif result:
print(result)
@async_function(on_done=on_async_done)
def do_expensive_stuff_in_thread(input_string):
# Pretend to do expensive stuff...
time.sleep(10)
stuff = input_string + ' Done in a different thread'
return stuff
do_expensive_stuff_in_thread(input_string)
'''
def wrapper(f):
def run(*args, **kwargs):
_async_call(f, args, kwargs, on_done)
return run
return wrapper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment