Pythonのasyncio.gather
は、複数の非同期タスクを並行して実行し、その結果を収集するための便利な関数です。しかし、これらのタスクの一つが例外を発生させた場合の挙動は、初めて使う人にとっては少し混乱を招くかもしれません。
デフォルトでは、asyncio.gather
は最初に発生した例外をすぐに伝播させます。これは、一つのタスクが失敗すると全体の結果が無効になるような場合(例えば、すべてのタスクの結果を合計するなど)には望ましい挙動です。
しかし、一部のタスクが失敗しても他のタスクの結果を得たい場合はどうすればよいでしょうか?そのためには、asyncio.gather
にreturn_exceptions=True
を渡すことで、例外を結果の一部として返すようにすることができます。
以下に、asyncio.gather
を使った例を示します。
import asyncio
async def task(name, raise_exception=False):
print(f'Task {name} started')
await asyncio.sleep(1)
if raise_exception:
raise Exception(f'Task {name} failed')
print(f'Task {name} completed')
return f'Task {name} result'
async def main():
tasks = [task('A'), task('B', raise_exception=True), task('C')]
results = await asyncio.gather(*tasks, return_exceptions=True)
print(results)
asyncio.run(main())
このコードでは、3つのタスクを定義し、そのうちの一つが例外を発生させます。asyncio.gather
のreturn_exceptions=True
オプションにより、例外が発生したタスクの結果はその例外オブジェクトとなります。そのため、main
関数のprint(results)
により、すべてのタスクの結果(成功したタスクの戻り値と、失敗したタスクの例外)が出力されます。
このように、asyncio.gather
を使うことで、複数の非同期タスクを効率的に扱い、その結果を適切に処理することができます。例外の扱い方に注意しながら、ぜひ活用してみてください。