class_docstr: Wrapper class that defines synchronous `_sync` method wrappers
  
  around async-native methods.
  
  Every coroutine method automatically gets an `_sync` alias
  that runs it synchronously.
class_docstr_tok: ["Wrapper","class","that","defines","synchronous","`","_sync","`","method","wrappers","around","async-native","methods",".","Every","coroutine","method","automatically","gets","an","`","_sync","`","alias","that","runs","it","synchronously","."]
docstr: Run an async function in a background thread
docstr_tok: ["Run","an","async","function","in","a","background","thread"]
code: def _in_thread(self, async_f, *args, **kwargs):
      """Run an async function in a background thread"""
      if self._async_thread is None:
          self._loop_started = threading.Event()
          self._async_thread = threading.Thread(
              target=self._thread_main, daemon=True
          )
          self._async_thread.start()
          self._loop_started.wait(timeout=5)
  
      future = concurrent.futures.Future()
  
      async def thread_callback():
          try:
              future.set_result(await async_f(*args, **kwargs))
          except Exception as e:
              future.set_exception(e)
  
      self._thread_loop.add_callback(thread_callback)
      return future.result()
  
file_path: ipyparallel/ipyparallel/_async.py
imports: import asyncio
  import concurrent.futures
  import inspect
  import threading
  from functools import partial
  from tornado.ioloop import IOLoop
label_desc: Use image node_id 2 for calling the AsyncFirst obj's underlying member method code with example usage: obj._in_thread(async_f) and returns: future