2017-07-08 40 views
3
async def start(channel): 
    while True: 
     m = await client.send_message(channel, "Generating... ") 
     generator.makeFile() 
     with open('tmp.png', 'rb') as f: 
      await client.send_file(channel, f) 
     await client.delete_message(m) 
     await asyncio.sleep(2) 

私は2秒ごとにタスクを実行する不協和音ボットを持っています。私はこれに無限ループを使用しようとしましたが、スクリプトはクラッシュしますTask was destroyed but it is still pending!私はasyncioのコルーチンについて読んだことがありますが、見つけた例はどれもawaitです。コルーチンをawaitで実行すると、このエラーを回避できますか?Asyncio、無限ループ、無限ループ

+0

ここでは「await」は問題ありません。さらにwhile whileは、定期的な呼び出しの一般的な方法です(https://stackoverflow.com/questions/37512182/how-can-i-periodically-execute-a-function-with-asyncio)。その関数をどのように実行するかを示します。コード内のタスクを停止しようとしていますか? – kwarunek

答えて

2

Task was destroyed but it is still pending!は、tasksの一部が完了していない場合にloop.close()に電話したときに表示されることを警告しています。未完了のタスクではリソースが解放されない可能性があるため、通常はこのような状況を避ける必要があります。イベントループを閉じる前に、完了したタスクまたはcancelを待つ必要があります。

あなたが無限ループを持っているので、おそらくタスク、例えば、キャンセルする必要があります:

import asyncio 
from contextlib import suppress 


async def start(): 
    # your infinite loop here, for example: 
    while True: 
     print('echo') 
     await asyncio.sleep(1) 


async def main(): 
    task = asyncio.Task(start()) 

    # let script some thime to work: 
    await asyncio.sleep(3) 

    # cancel task to avoid warning: 
    task.cancel() 
    with suppress(asyncio.CancelledError): 
     await task # await for task cancellation 


loop = asyncio.new_event_loop() 
asyncio.set_event_loop(loop) 
try: 
    loop.run_until_complete(main()) 
finally: 
    loop.run_until_complete(loop.shutdown_asyncgens()) 
    loop.close() 

のタスクの詳細についてもthis answer参照してください。

+0

[その答え](https://stackoverflow.com/a/37345564/1113207)は完璧に、ありがとう。 この例はうまくいきますが、無限ループがあるポイントまたは別のポイントで停止する必要があると思われます。 – user8245289