Сбой метода `get` QNetworkAccessManager при перезапуске

В настоящее время я добавляю в свое приложение функциональность, которая позволит перезапустить его.

Вот так выглядит основная

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, упомянутого ниже. Метод get QNetworkAccessManager возвращает ошибку блокировки. Вот как выглядит мой код

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 и метод return_from_event_loop_code = app->exec(); в main вызывается снова, на этот раз в операторе currentReply = networkManager->get(request); в MethodA, приложение аварийно завершает работу и заканчивается

mlock.c

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

Любая идея о том, почему приложение дает сбой в операторе get QNetworkAccessManager, когда приложению дается инструкция перезапустить?


person Rajeshwar    schedule 25.04.2014    source источник


Ответы (1)


Я провел расследование крушения. Это действительно вызвано разрушением QApplication. QNetworkAccessManager внутренне использует объект QNetworkConfigurationManagerPrivate. Этот объект создается по мере необходимости и используется до завершения работы приложения. Функция qNetworkConfigurationManagerPrivate используется для создания или получения существующего объекта.

Когда QApplication уничтожается, он выполняет все пост-процедуры, включая connManager_cleanup. Эта функция косвенно уничтожает QNetworkConfigurationManagerPrivate объект и устанавливает appShutdown локальный флаг. Когда этот флаг установлен, функция qNetworkConfigurationManagerPrivate больше не будет создавать новые объекты QNetworkConfigurationManagerPrivate. Так что после уничтожения QApplication QNetworkAccessManager становится нефункциональным.

Я думал, что это неправильное использование объекта QApplication, но недавно я нашел ссылку, подтверждающую правильность использования.

Соглашения о кодировании Qt гласят:

Q[Core]Application — это одноэлементный класс. Одновременно может быть только один экземпляр. Однако этот экземпляр можно уничтожить и создать новый.

Так что эту проблему следует считать ошибкой Qt.

person Pavel Strakhov    schedule 26.04.2014
comment
Это неправильно? stackoverflow.com/questions/5129788 / - person Rajeshwar; 26.04.2014
comment
Да, я думаю, что ответы, которые советуют воссоздать QApplication, неверны (хотя они не принимаются, и самый высоко оцененный ответ кажется правильным). Я добавил больше деталей в свой ответ. - person Pavel Strakhov; 26.04.2014