asyncio - how to stop background task cleanly

Frank Millman frank at chagford.com
Sun Feb 7 03:55:58 EST 2016


"Marko Rauhamaa"  wrote in message news:87r3gpq7mi.fsf at elektro.pacujo.net...
>
> I can't see your complete program, but here's mine, and it seems to be 
> working
>

Thanks, Marko, I really appreciate your assistance.

I wanted to show you my complete program, but as it is quite long I 
distilled it down to its essence, and lo and behold it works!

So now I just have to go through my program and find where it differs - I 
must have a bug somewhere.

For the record, here is my stripped down version.

The main difference from yours is that I want to run a genuine 'loop 
forever', and only shut it down on receipt of some external signal.

I have never been able to get Ctrl+C to work properly on Windows, so I use a 
separate thread that simply waits for Enter.

You will see that if you press Enter after 'done' appears, the program 
closes instantly, but if you press it in between 'start' and 'done', it 
waits for the task to complete before it closes.

Frank

=============================================================

import asyncio, time
import threading

def main():
    loop = asyncio.get_event_loop()
    task = asyncio.async(background_task())
    threading.Thread(target=stop, args=(loop, task)).start()
    loop.run_forever()

@asyncio.coroutine
def background_task():
    try:
        while True:
            print('start')
            time.sleep(2)
            print('done')
            yield from asyncio.sleep(5)
    except asyncio.CancelledError:
        print('cleanup')
    print('DONE')

@asyncio.coroutine
def shutdown(loop, task):
    task.cancel()
    yield from asyncio.wait([task], loop=loop)
    loop.stop()

def stop(loop, task):
    input('Press <enter> to stop\n')
    asyncio.run_coroutine_threadsafe(shutdown(loop, task), loop)

if __name__ == '__main__':
    main()




More information about the Python-list mailing list