【问题标题】:QNetworkAccessManager `get` method crashes on restartQNetworkAccessManager `get` 方法在重启时崩溃
【发布时间】:2014-04-25 20:59:10
【问题描述】:

我目前正在向我的应用程序添加一项允许它重新启动的功能。

这是主要的样子

int main(int argc, char *argv[])
{
    const int RESTART_CODE = 1000;
    int return_from_event_loop_code;
    QPointer<QApplication> app;
    QPointer<foo> main_window;
    do
    {
        if(main_window)
            delete main_window; 
        if(app) 
            delete app;

            app = new QApplication(argc, argv);
            main_window = new foo();
            main_window->show();
            app->setActiveWindow(main_window);

            return_from_event_loop_code = app->exec();
    } 
    while(return_from_event_loop_code==RESTART_CODE);

  return return_from_event_loop_code;
}

现在第一次运行良好,但是当使用下面提到的RestartApp 方法重新启动应用程序时。 QNetworkAccessManager的get方法返回锁错误。这就是我的代码的样子

void foo::MethodA()
{
    ....
    ....
    QUrl url("some url");
    QNetworkRequest request;
    request.setUrl(url);
    networkManager = new QNetworkAccessManager(this);
    QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)),static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
    currentReply = networkManager->get(request); //Crashes when the app is restarted again
    connect(currentReply, SIGNAL(error(QNetworkReply::NetworkError)),this, SLOT(slotNetworkError(QNetworkReply::NetworkError)),Qt::UniqueConnection);
}

//Slot
void foo::replyFinished(QNetworkReply* rply)
{
    ....
    .....
    rply->deleteLater();
}

//Slot
void foo::RestartApp()
{
    QCoreApplication::exit(1000);
}

现在,当应用程序第一次启动时会发生什么,一切都很好。但是,当调用 RestartApp 方法并且这次在 MethodA 中的语句 currentReply = networkManager-&gt;get(request); 再次调用 main 中的 return_from_event_loop_code = app-&gt;exec(); 方法时,应用程序崩溃并最终在

mlock.c

void __cdecl _unlock (
        int locknum
        )
{
        /*
         * leave the critical section.
         */
        LeaveCriticalSection( _locktable[locknum].lock );
}

知道为什么应用程序在收到重启指令时会在 QNetworkAccessManager 的 get 语句中崩溃吗?

【问题讨论】:

    标签: c++ qt sockets qnetworkaccessmanager qnetworkrequest


    【解决方案1】:

    我已经对坠机事件进行了一些调查。这确实是由QApplication 的破坏引起的。 QNetworkAccessManager 在内部使用 QNetworkConfigurationManagerPrivate 对象。该对象在需要时创建并使用,直到应用程序完成。 qNetworkConfigurationManagerPrivate 函数用于创建或获取现有对象。

    QApplication 被销毁时,它会执行所有的post 例程,包括connManager_cleanup。此函数间接销毁QNetworkConfigurationManagerPrivate 对象并设置appShutdown 本地标志。设置此标志后,qNetworkConfigurationManagerPrivate 函数将不再创建新的QNetworkConfigurationManagerPrivate 对象。所以QApplication 销毁后QNetworkAccessManager 就失效了。

    我以为是QApplication对象的误用,但最近我发现了一个证明链接,证明使用是正确的。

    Qt 的Coding Conventions 状态:

    Q[Core]Application 是一个单例类。一次只能有一个实例。但是,可以销毁该实例并创建一个新实例。

    所以这个问题应该被认为是一个 Qt 错误。

    【讨论】:

    • 是的,我认为建议重新创建 QApplication 的答案是不正确的(尽管它们不被接受,而且评分最高的答案似乎是正确的)。我在回答中添加了更多细节。
    猜你喜欢
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多