zoukankan      html  css  js  c++  java
  • QNetworkAccessManager的异步与线程

    Qt版本5.1.1

    以HTTP操作为例

    Qt中的HTTP操作都是异步的. 内部通过线程实现

    创建线程的时机在QNetworkReplyHttpImplPrivate::postRequest()

    void QNetworkReplyHttpImplPrivate::postRequest()
    {
        Q_Q(QNetworkReplyHttpImpl);
    
        QThread *thread = 0;
        if (synchronous) {
            // A synchronous HTTP request uses its own thread
            thread = new QThread();
            thread->setObjectName(QStringLiteral("Qt HTTP synchronous thread"));
            QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
            thread->start();
        } else if (!managerPrivate->httpThread) {
            // We use the manager-global thread.
            // At some point we could switch to having multiple threads if it makes sense.
            managerPrivate->httpThread = new QThread();
            managerPrivate->httpThread->setObjectName(QStringLiteral("Qt HTTP thread"));
            managerPrivate->httpThread->start();
    
            thread = managerPrivate->httpThread;
        } else {
            // Asynchronous request, thread already exists
            thread = managerPrivate->httpThread;
        }
    
    ..........
    
        // Move the delegate to the http thread
        delegate->moveToThread(thread);
        // This call automatically moves the uploadDevice too for the asynchronous case.
    
    ...........
    }


    分为两种情况:
    (1) synchronous == true 每次HTTP请求创建自己的线程, 并在finished后自动退出线程

    在QNetworkRequest设置QNetworkRequest::SynchronousRequestAttribute 属性为真时, synchronous = true, 然而SynchronousRequestAttribute被Qt标记为internal. 以防止外部创建synchronous HTTP请求.
    我在Qt的源码中找到一点说明, QNetworkReplyHttpImpl的构造函数中.

    ........
       // Internal code that does a HTTP reply for the synchronous Ajax
        // in Qt WebKit.
        QVariant synchronousHttpAttribute = request.attribute(
                static_cast<QNetworkRequest::Attribute>(QNetworkRequest::SynchronousRequestAttribute));
        if (synchronousHttpAttribute.isValid()) {
            d->synchronous = synchronousHttpAttribute.toBool();
    ........

    webkit的ajax请求使用


    (2) synchronous == false 则把所有http请求放置在一个线程中.
    并且该线程在
    QNetworkAccessManagerPrivate对象析构(即QNetworkAccessManager析构)或者调用QNetworkAccessManagerPrivate::clearCache 时退出

    QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
    {
        if (httpThread) {
            httpThread->quit();
            httpThread->wait(5000);
            if (httpThread->isFinished())
                delete httpThread;
            else
                QObject::connect(httpThread, SIGNAL(finished()), httpThread, SLOT(deleteLater()));
            httpThread = 0;
        }
    }
    
    void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager)
    {
        manager->d_func()->objectCache.clear();
        manager->d_func()->authenticationManager->clearCache();
    
        if (manager->d_func()->httpThread) {
            manager->d_func()->httpThread->quit();
            manager->d_func()->httpThread->wait(5000);
            if (manager->d_func()->httpThread->isFinished())
                delete manager->d_func()->httpThread;
            else
                QObject::connect(manager->d_func()->httpThread, SIGNAL(finished()), manager->d_func()->httpThread, SLOT(deleteLater()));
            manager->d_func()->httpThread = 0;
        }
    }

    否则会一直HTTP 线程会一直存在. 另外, 每个QNetworkAccessManager对象对应自己的HTTP thread.

  • 相关阅读:
    对象 函数
    流程控制语句 label 从键盘输入 计时器 []中括号的使用
    类型转换 运算符 流程控制语句
    JS的编写的位置 输出语句 注释 字面量和变量 数据类型
    AutoCad 二次开发 .net 之创建Table
    AutoCad 二次开发 .net 之相同块的自动编号
    Java 多线程练习
    C# Winform 自定义控件——竖着的Navbar
    C# Winfrom 自定义控件——带图片的TextBox
    Task CancellationTokenSource和Task.WhenAll的应用
  • 原文地址:https://www.cnblogs.com/lingdhox/p/3456413.html
Copyright © 2011-2022 走看看