2017-11-27 8 views
1

私はasyncioループを実行するスレッドを持っています。私はここで無関係なことをする将来の仕事を始める。スレッドを停止すると、asyncioループも停止します。それは出力実行スレッドとasyncio:タスクは破棄されましたが保留中です

from contextlib import suppress 
from threading import Thread 
from time import sleep 
import asyncio 


class Hardware(Thread): 

    def __init__(self, *args, **kwargs): 
     super(Hardware, self).__init__(*args, **kwargs) 
     self.loop = None 
     self._poll_task = None 

    def run(self): 
     self.loop = asyncio.new_event_loop() 
     asyncio.set_event_loop(self.loop) 
     self.loop.create_task(self._poll()) 
     self.loop.run_forever() 

    async def _poll(self): 
     print('ook') 
     await asyncio.sleep(1.0) 
     self._poll_task = asyncio.ensure_future(self._poll()) 
     return self._poll_task 

    def stop(self): 
     if self._poll_task is not None: 
      self.loop.call_soon_threadsafe(self._poll_task.cancel) 
     with suppress(asyncio.CancelledError): 
      self.loop.call_soon_threadsafe(self.loop.stop) 


hw = Hardware() 
try: 
    hw.start() 
    while True: 
     sleep(.1) 
except KeyboardInterrupt: 
    hw.stop() 
    hw.join() 

::私は間違って何をやっている

; python ook.py 
ook 
ook 
^CTask was destroyed but it is pending! 
task: <Task pending coro=<Hardware._poll() running at ook.py:22> wait_for=<Future cancelled>> 

しかし、私はプールのタスクをキャンセルし、Task was destroyed but it is pending!ここ

は、おもちゃの一例であるように見えることはできませんか?

+0

私は、より良い起動/シャットダウンのためにコードをリファクタリングしました。 –

答えて

2

あなただけがそうであるように、単にループを停止するのではなく、タスクのcancel()、だけでなく、await its cancellationを呼び出すべきではありません。

from contextlib import suppress 
from threading import Thread 
from time import sleep 
import asyncio 


class Hardware(Thread): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.loop = None 
     self._poll_task = None 

    def run(self): 
     self.loop = asyncio.new_event_loop() 
     loop = self.loop 
     asyncio.set_event_loop(loop) 
     try: 
      # create task: 
      self._poll_task = asyncio.ensure_future(self._poll()) 

      # run loop: 
      loop.run_forever() 
      loop.run_until_complete(loop.shutdown_asyncgens()) 

      # cancel task: 
      self._poll_task.cancel() 
      with suppress(asyncio.CancelledError): 
       loop.run_until_complete(self._poll_task) 
     finally: 
      loop.close() 

    def stop(self): 
     self.loop.call_soon_threadsafe(self.loop.stop) 

    async def _poll(self): 
     while True: # you don't need to create new task each time 
      print('ook') 
      await asyncio.sleep(1.0) 


hw = Hardware() 
try: 
    hw.start() 
    while True: 
     sleep(.1) 
except KeyboardInterrupt: 
    hw.stop() 
    hw.join() 
関連する問題