def METHOD_NAME(*args, **kwargs):
    if ThreadRouter.app_is_shutting_down:
        logger.warning("Won't execute threadRouted function %s because app is shutting down", func)
        return
    router = threadRouter
    if router is None:
        assert len(args) > 0
        obj = args[0]
        assert isinstance(obj, QObject)
        assert hasattr(
            obj, "threadRouter"
        ), "Can't use the @threadRouted decorator unless your object has a member called self.threadRouter"
        router = obj.threadRouter
    # If we're already in the parent thread, then we can call the function directly
    if router.ident == threading.current_thread().ident:
        val = func(*args, **kwargs)
        # We rely on Qt signals (below) so it is an error to
        #  use @threadRouted with a function that gives a return value
        assert val is None, "Can't return a value from an @threadRouted function."
    # Otherwise, we rely on the Qt BlockingQueuedConnection
    #  signal behavior to transfer the call to the parent thread.
    else:
        router.routeToParent.emit(partial(func, *args, **kwargs))