fix run async execution error

This commit is contained in:
Xuwznln
2025-10-31 21:43:25 +08:00
parent 61e8d67800
commit 062f1a2153
2 changed files with 12 additions and 49 deletions

View File

@@ -53,7 +53,7 @@ from unilabos.ros.nodes.resource_tracker import (
) )
from unilabos.ros.x.rclpyx import get_event_loop from unilabos.ros.x.rclpyx import get_event_loop
from unilabos.ros.utils.driver_creator import WorkstationNodeCreator, PyLabRobotCreator, DeviceClassCreator from unilabos.ros.utils.driver_creator import WorkstationNodeCreator, PyLabRobotCreator, DeviceClassCreator
from unilabos.utils.async_util import run_async_func from rclpy.task import Task
from unilabos.utils.import_manager import default_manager from unilabos.utils.import_manager import default_manager
from unilabos.utils.log import info, debug, warning, error, critical, logger, trace from unilabos.utils.log import info, debug, warning, error, critical, logger, trace
from unilabos.utils.type_check import get_type_class, TypeEncoder, get_result_info_str from unilabos.utils.type_check import get_type_class, TypeEncoder, get_result_info_str
@@ -1385,18 +1385,19 @@ class ROS2DeviceNode:
它不继承设备类,而是通过代理模式访问设备类的属性和方法。 它不继承设备类,而是通过代理模式访问设备类的属性和方法。
""" """
# 类变量,用于循环管理
_loop = None
_loop_running = False
_loop_thread = None
@classmethod @classmethod
def get_loop(cls): def run_async_func(cls, func, trace_error=True, **kwargs) -> Task:
return cls._loop def _handle_future_exception(fut):
try:
fut.result()
except Exception as e:
error(f"异步任务 {func.__name__} 报错了")
error(traceback.format_exc())
@classmethod future = rclpy.get_global_executor().create_task(func(**kwargs))
def run_async_func(cls, func, trace_error=True, **kwargs): if trace_error:
return run_async_func(func, loop=cls._loop, trace_error=trace_error, **kwargs) future.add_done_callback(_handle_future_exception)
return future
@property @property
def driver_instance(self): def driver_instance(self):
@@ -1436,11 +1437,6 @@ class ROS2DeviceNode:
print_publish: 是否打印发布信息 print_publish: 是否打印发布信息
driver_is_ros: driver_is_ros:
""" """
# 在初始化时检查循环状态
if ROS2DeviceNode._loop_running and ROS2DeviceNode._loop_thread is not None:
pass
elif ROS2DeviceNode._loop_thread is None:
self._start_loop()
# 保存设备类是否支持异步上下文 # 保存设备类是否支持异步上下文
self._has_async_context = hasattr(driver_class, "__aenter__") and hasattr(driver_class, "__aexit__") self._has_async_context = hasattr(driver_class, "__aenter__") and hasattr(driver_class, "__aexit__")
@@ -1529,17 +1525,6 @@ class ROS2DeviceNode:
except Exception as e: except Exception as e:
self._ros_node.lab_logger().error(f"设备后初始化失败: {e}") self._ros_node.lab_logger().error(f"设备后初始化失败: {e}")
def _start_loop(self):
def run_event_loop():
loop = asyncio.new_event_loop()
ROS2DeviceNode._loop = loop
asyncio.set_event_loop(loop)
loop.run_forever()
ROS2DeviceNode._loop_thread = threading.Thread(target=run_event_loop, daemon=True, name="ROS2DeviceNodeLoop")
ROS2DeviceNode._loop_thread.start()
logger.info(f"循环线程已启动")
class DeviceInfoType(TypedDict): class DeviceInfoType(TypedDict):
id: str id: str

View File

@@ -1,22 +0,0 @@
import asyncio
import traceback
from asyncio import get_event_loop
from unilabos.utils.log import error
def run_async_func(func, *, loop=None, trace_error=True, **kwargs):
if loop is None:
loop = get_event_loop()
def _handle_future_exception(fut):
try:
fut.result()
except Exception as e:
error(f"异步任务 {func.__name__} 报错了")
error(traceback.format_exc())
future = asyncio.run_coroutine_threadsafe(func(**kwargs), loop)
if trace_error:
future.add_done_callback(_handle_future_exception)
return future