笔者开发的软件在关闭界面时,报错:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x236cc255c90. Receiver '' (of type 'ModbusManager') was created in thread 0x0x236d073b370", file kernel\qcoreapplication.cpp, line 573 

说明在析构过程中还有跨线程的对象访问。问题出现在析构函数中。说明在析构函数中没有正确终止线程/还有尚未结束的操作:未关闭的串口等

示例:这个类实现的是加热控制器设备控制,该类通信协议是Modbus RTU ,使用串口连接设备,两个设备的通信过程都各自创建了一个子线程来完成。

HeatingControllerWin::~HeatingControllerWin()
{
    // 先停止主线程中使用的定时器
    if (m_refreshTimer && m_refreshTimer->isActive()) {
        m_refreshTimer->stop();
    }
    
    // 使用信号来断开串口Modbus通信,确保在正确的线程执行
    if (m_modbusManager1) {
        // 使用 QMetaObject::invokeMethod 确保在对象所属线程执行断开操作
        QMetaObject::invokeMethod(m_modbusManager1, "disconnectController", 
                                Qt::BlockingQueuedConnection);
    }
    if (m_modbusManager2) {
        QMetaObject::invokeMethod(m_modbusManager2, "disconnectController", 
                                Qt::BlockingQueuedConnection);
    }
    
    // 停止串口通信所在的子线程
    if (m_modbusThread1 && m_modbusThread1->isRunning()) {
        m_modbusThread1->quit();
        if (!m_modbusThread1->wait(1000)) { // 等待1秒
            m_modbusThread1->terminate(); // 如果正常退出失败,强制终止
            m_modbusThread1->wait();
        }
    }
    
    if (m_modbusThread2 && m_modbusThread2->isRunning()) {
        m_modbusThread2->quit();
        if (!m_modbusThread2->wait(1000)) {
            m_modbusThread2->terminate();
            m_modbusThread2->wait();
        }
    }
    
    // 注意:不要在这里手动删除 m_modbusManager1 和 m_modbusManager2 串口通信类对象
    // 因为它们有父对象(线程),会在线程销毁时自动删除
    
    btnCount = 0;
}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐