QNetworkAccessManager`get`方法在重启时崩溃

时间:2014-04-25 20:59:11

标签: c++ qt sockets qnetworkaccessmanager qnetworkrequest

我目前正在为我的应用添加一项功能,以便重新启动。

这就是主要的样子

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中的语句return_from_event_loop_code = app->exec();再次调用main中的currentReply = networkManager->get(request);方法时,应用程序崩溃并最终进入

mlock.c

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

当应用程序被指示重启时,有什么想法应用程序在QNetworkAccessManager的get语句上崩溃的原因吗?

1 个答案:

答案 0 :(得分:0)

我对坠机做了一些调查。它确实是由QApplication的破坏引起的。 QNetworkAccessManager在内部使用QNetworkConfigurationManagerPrivate对象。在需要时创建此对象,并在应用程序完成之前使用。 qNetworkConfigurationManagerPrivate函数用于创建或获取现有对象。

QApplication被销毁时,它会执行所有后期例程,包括connManager_cleanup。此函数间接销毁QNetworkConfigurationManagerPrivate对象并设置appShutdown本地标志。设置此标志后,qNetworkConfigurationManagerPrivate函数将不再创建新的QNetworkConfigurationManagerPrivate对象。因此,QApplication QNetworkAccessManager的破坏变得无效后。

我认为这是对QApplication对象的误用,但最近我找到了一个证据链接,证明使用是正确的。

Qt&#39; Coding Conventions州:

  

Q [核心]应用程序是单例类。一次只能有一个实例。但是,该实例可以被销毁,并且可以创建一个新实例。

所以这个问题应该被视为Qt bug。