首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QNetworkReply网络应答超时助手

QNetworkReply网络应答超时助手
EN

Code Review用户
提问于 2013-08-21 12:59:30
回答 1查看 10.9K关注 0票数 11

由于Qt仍然不支持在QNetworkRequest对象上设置超时,所以我编写了这个小包装类:

代码语言:javascript
复制
/**
Usage:
new QReplyTimeout(yourReply, msec);

When the timeout is reached the given reply is closed if still running
*/
class QReplyTimeout : public QObject {
  Q_OBJECT
public:
  QReplyTimeout(QNetworkReply* reply, const int timeout) : QObject(reply) {
    Q_ASSERT(reply);
    if (reply) {
      QTimer::singleShot(timeout, this, SLOT(timeout()));
    }
  }

private slots:
  void timeout() {
    QNetworkReply* reply = static_cast<QNetworkReply*>(parent());
    if (reply->isRunning()) {
      reply->close();
    }
  }
};

您可以以一种非常简单的火和遗忘的方式使用它:

代码语言:javascript
复制
QNetworkAccessManager networkAccessManger;
QNetworkReply* reply = networkAccessManger.get(QNetworkRequest(QUrl("https://www.google.com")));
new QReplyTimeout(r, 100);

如果对Google的调用没有在100 is内完成,它将被中止。而且,由于QReplyTimeout类是QNetworkReply的父类,它将被自动销毁。

检查代码中是否存在任何缺陷、内存泄漏、无效的强制转换,以及它是否具有良好的风格。

EN

回答 1

Code Review用户

发布于 2016-05-25 17:38:07

以下是我的想法:

  1. 这是一个简单的类,在堆上分配了很多次。您可以最小化它所做的隐式分配的数量。QTimer::singleShot创建一个临时QObject实例,并在堆上分配一堆。您可以通过使用timerEvent显式地处理单次定时器来避免这种情况。您还避免了以这种方式设置任何连接的需要。当第一个连接被添加到QObject时,它会执行大约两次分配。
  2. 使用Qt-5风格的连接,但这不再适用于上面的#1。
  3. 添加使用此类设置网络请求超时的静态助手方法。您需要分配ReplyTimeout这一事实是可以以这种方式抽象出来的各种实现细节。
  4. 在设置超时之前,检查回复是否正在运行。也许这是一个不正确的/不可能的请求,当它被提交给经理时,它立即完成了。
  5. 不应该用Q前缀命名类。这是为Qt预留的。

下面的代码可以跨Qt 4和Qt 5移植:

代码语言:javascript
复制
class ReplyTimeout : public QObject {
  Q_OBJECT
  QBasicTimer m_timer;
public:
  ReplyTimeout(QNetworkReply* reply, const int timeout) : QObject(reply) {
    Q_ASSERT(reply);
    if (reply && reply->isRunning())
      m_timer.start(timeout, this);
  }
  static void set(QNetworkReply* reply, const int timeout) {
    new ReplyTimeout(reply, timeout);
  }
protected:
  void timerEvent(QTimerEvent * ev) {
    if (!m_timer.isActive() || ev->timerId() != m_timer.timerId())
      return;
    auto reply = static_cast<QNetworkReply*>(parent());
    if (reply->isRunning())
      reply->close();
    m_timer.stop();
  }
};

使用:

代码语言:javascript
复制
QNetworkAccessManager networkAccessManger;
QNetworkReply* reply = 
  networkAccessManger.get(QNetworkRequest(QUrl("https://www.google.com")));
ReplyTimeout::set(reply, 100);
票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/30031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档