如何终止Tornado spawn_task生成的WebSocket后台任务
解决Tornado WebSocket连接关闭时终止后台任务的方案
要终止WebSocket连接建立时启动的后台任务,核心是保存任务引用并在连接关闭时主动取消任务,同时在任务内部处理终止逻辑。以下是修改后的完整代码及关键说明:
import asyncio from tornado.websocket import WebSocketHandler from tornado.ioloop import IOLoop class MyHandler(WebSocketHandler): def open(self, device: str): # 将后台任务的引用保存到实例属性中 self.background_task = IOLoop.current().spawn_task(self._background_task) async def _background_task(self): try: while True: # 先检查连接状态,避免连接关闭后继续执行无效逻辑 if not self.ws_connection or self.ws_connection.is_closed(): break # 这里编写你的重复执行逻辑 print(f"Device {self.path_args[0]}: Running background task...") # 必须加入await操作让出事件循环,否则会阻塞整个IOLoop await asyncio.sleep(1) except asyncio.CancelledError: # 捕获任务取消异常,实现优雅退出 pass finally: # 可选:添加资源清理逻辑 print(f"Device {self.path_args[0]}: Background task stopped.") def on_close(self): # 检查任务是否存在且未完成,再执行取消操作 if hasattr(self, 'background_task') and not self.background_task.done(): self.background_task.cancel() def on_message(self, message): print(f"Received message: {message}")
关键实现细节:
- 保存任务引用:在
open方法中,将spawn_task返回的Future对象赋值给self.background_task,确保后续能访问并操作该任务。 - 任务内的终止条件:循环中先检查
self.ws_connection的状态,一旦连接关闭就主动跳出循环,避免无意义的资源消耗。 - 处理取消异常:调用
cancel()会触发asyncio.CancelledError,捕获该异常可以让任务优雅退出,避免控制台报错。 - 安全取消任务:在
on_close中先判断任务是否存在且未完成,再执行取消操作,防止对已完成的任务执行无效操作。
内容的提问来源于stack exchange,提问作者DumTux
相关产品推荐
相关产品推荐

