title: When you need to use AsyncIO and ThreadPoolExecutor, do you need to call loop.close() manually?
body: <p>In the Python <a href="https://docs.python.org/3/library/asyncio-eventloop.html#running-and-stopping-the-loop" rel="noreferrer">docs</a>, it states:</p>
  
  <blockquote>
    <p>Application developers should typically use the high-level asyncio
    functions, such as asyncio.run(), and should rarely need to reference
    the loop object or call its methods.
    <strong>This section is intended mostly for authors of lower-level code, libraries, and frameworks, who need finer control over the event loop behavior.</strong></p>
  </blockquote>
  
  <p>When using both <code>async</code> and a <code>threadpoolexecutor</code>, as show in the example code (from the docs):</p>
  
  <pre><code>import asyncio
  import concurrent.futures
  
  def blocking_io():
      # File operations (such as logging) can block the
      # event loop: run them in a thread pool.
      with open('/dev/urandom', 'rb') as f:
          return f.read(100)
  
  async def main():
      loop = asyncio.get_running_loop()
  
      # 2. Run in a custom thread pool:
      with concurrent.futures.ThreadPoolExecutor() as pool:
          result = await loop.run_in_executor(
              pool, blocking_io)
          print('custom thread pool', result)
  
  asyncio.run(main()) 
  </code></pre>
  
  <ol>
  <li>Do I need to call <code>loop.close()</code>, or would the <code>asyncio.run()</code> close the loop for me?</li>
  <li>Is using both <code>asyncio</code> and <code>threadpoolexecutor</code> together, one of those situations where you need <em>finer control over the event loop</em>? Can using both, <code>asyncio</code> and <code>threadpoolexecutor</code> together be done without referencing the <code>loop</code>?</li>
  </ol>