On Mon, Apr 2, 2018 at 5:32 AM, <jf...@ms4.hinet.net> wrote: > I am new to the asyncio subject, just trying to figure out how to use it. > Below is the script I use for testing: > --------------------------------- > # asyncio_cancel_task2.py > > import asyncio > > @asyncio.coroutine > def task_func(): > print('in task_func, sleeping') > try: > yield from asyncio.sleep(1) > except asyncio.CancelledError: > print('task_func was canceled') > raise > print('return result') > return 'the result' > > def task_canceller(task): > task.cancel() > print('canceled the task') > > @asyncio.coroutine > def main(loop): > print('first, scheduling a task') > task = loop.create_task(task_func()) > print('second, scheduling its cancellation') > loop.call_later(0.5, task_canceller, task) > try: > print('waiting task to complete') > yield from task > except asyncio.CancelledError: > print('main() also sees task as canceled') > > > event_loop = asyncio.get_event_loop() > try: > event_loop.run_until_complete(main(event_loop)) > finally: > print('wait 3 seconds before closing event_loop') > asyncio.sleep(3)
This won't actually wait 3 seconds. It just instantiates a sleep coroutine and then discards it. Inside the event loop you would need to await or yield from it. Outside the event loop, in order to sleep you have to block the thread, e.g. using time.sleep. That said, there is no reason to wait before closing the event loop. > print('event_loop was closed') > event_loop.close() > ----------------------------------- > > It schedules two tasks, the task_func and the task_canceller, in main. Before > the task_func completed, the task_canceller was fired to cancel it. Hence its > output below seems reasonable. > > D:\Works\Python>py > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit > (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> import asyncio_cancel_task2 > first, scheduling a task > second, scheduling its cancellation > waiting task to complete > in task_func, sleeping > canceled the task > task_func was canceled > main() also sees task as canceled > wait 3 seconds before closing event_loop > event_loop was closed >>>> > > Then, I changed the call_later delay from 0.5 to 1.5, expect it to be called > after the task_func completed and before the event loop closed. The output > seems not quite right. Why the task_canceller hasn't been called? > >>>> import asyncio_cancel_task2 > first, scheduling a task > second, scheduling its cancellation > waiting task to complete > in task_func, sleeping > return result > wait 3 seconds before closing event_loop > event_loop was closed >>>> Because, as your thread title suggests, after run_until_complete returns, the event loop is not running. How could it? It needs a thread to run on, but it doesn't create one, so whenever it returns from running it is relinquishing the thread and can't do anything unless it gets it back, since that thread is now running outer code. If you want to, you can restart the event loop by calling one of the run methods again; everything that was previously scheduled and everything that was scheduled after it stopped will remain scheduled. So, you can't have the event loop running in the background while also doing things within the code that started the loop in the same thread. If you really want this you can create a second thread to run the event loop on. However it is usually better to do that sort of thing within a coroutine running in the event loop, since single-threaded concurrency is the whole point of asyncio. The code that started the event loop will then only be used for cleanup after it terminates. -- https://mail.python.org/mailman/listinfo/python-list