【问题标题】:QThread and implementation of notifyQThread和notify的实现
【发布时间】:2016-07-01 11:14:26
【问题描述】:

在多线程 Qt 应用程序中重新实现 notify 函数时要注意什么? 这是一个示例实现。 目前没有错误,但我担心可能会出现错误,因为 Qt 中的多线程使用使用通知功能的信号槽进行通信。

TApplication::notify(QObject *receiver, QEvent *event)
{
    bool returnValue(false);
    try
    {
        returnValue = QApplication::notify(receiver, event);
    }
    catch (IExceptionBase& e)
    {
        if (!fMain.isNull())
        {
            //report error to output and file log
        }
        else
        {
            //report error to output
        }
    }
    catch (...)
    {
        if (!fMain.isNull())
        {
            //report error to output and file log
        }
        else
        {
            //report error to output
        }
    }
    return returnValue;
}

fMain 是一个具有报告功能的模块

【问题讨论】:

    标签: c++ qt qthread qapplication


    【解决方案1】:

    在 Qt5 中,这是安全的。但是,from the documentation,在 Qt6 中这将不再在主线程之外工作,事实上,该函数正在考虑在 Qt6 中完全弃用。

    正如 Kuba Ober 指出的那样,重新实现 notify 来捕获异常是一个坏主意,因为其他线程中的事件和任何排队的信号都是异步传递的。

    【讨论】:

    • 重新实现notify 是为了实现一个全面的“包罗万象”异常接收器。 postEvent 与此无关,因为事件处理程序不会在其中执行。
    • @KubaOber:Doh。缺少函数签名和代码缩进让我对作者的实际(相对于陈述的)目的感到困惑。我会修正我的答案。
    【解决方案2】:

    notify 中捕获所有异常是一种反模式。过去这样做很酷,但结果证明是个坏主意。所以不要那样做。如果您的插槽或事件处理程序抛出异常,请将其代码包装在 try-catch 块中。 notify 给你一种错误的安全感,因为在很多情况下,信号和直接连接的插槽恰好是从事件处理程序中调用的。但有时情况并非如此,您的代码会由于未处理的异常而崩溃。

    确保您熟悉Core C++ Error Handling GuidelinesC++ Exceptions and Error Handling FAQ

    【讨论】:

    • 我将全力以赴并强化这个想法:codereview.qt-project.org/#/c/162682/3/src/corelib/kernel/…
    • @peppe,所以如果我使用 deleteLater 之类的东西,在 qt5 中的通知中捕获所有异常并不是一种反模式,对吧?那么它是捕获异常而不是事件处理程序的唯一方法吗?
    • @user150497 这与deleteLater 或其他任何事情无关。 不要让异常离开插槽和事件处理程序。 就我而言,Qt 应该检测到这一点,如果这种滥用持续存在,Qt 应该在调试模式下使断言失败(不仅仅是发出警告)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 2013-06-19
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多