When an asynchronous generator is about to be garbage collected,
   it calls its cached finalizer.  The assumption is that the finalizer
   will schedule an ``aclose()`` call with the loop that was active
   when the iteration started.

   For instance, here is how asyncio can be modified to allow
   safe finalization of asynchronous generators::

       # asyncio/base_events.py

       class BaseEventLoop:

           def run_forever(self):
               ...
               old_finalizer = sys.get_asyncgen_finalizer()
               sys.set_asyncgen_finalizer(self._finalize_asyncgen)
               try:
                   ...
               finally:
                   sys.set_asyncgen_finalizer(old_finalizer)
                   ...

           def _finalize_asyncgen(self, gen):
               self.create_task(gen.aclose())

   ``sys.set_asyncgen_finalizer`` is thread-specific, so several event
   loops running in parallel threads can use it safely.

When asynchronous generator is about to be garbage collected event loop starts task to execute aclose, right? Can't such situation happen when this task is not finished at the moment event loop is closed? Something like:

async def gen():
    try:
        yield 1
        yield 2
        yield 3
    except GeneratorExit as exc:
        await asyncio.sleep(100)
        raise exc


async def main():
    async for i in gen():
        if i == 1:
            break

    # main() and event loop is about to finish here,
    # while task to aclose will last much longer.


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())