Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to abort all the requests of the QNetworkAccessManager
Qt 6.11 is out! See what's new in the release blog

How to abort all the requests of the QNetworkAccessManager

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 8.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Hi

    I'm currently working on an uploader with multiple files and I wish to be able to cancel all the ongoing calls. The structure of the app is the following.

    I have a uploader that gets moved to a seperate thread. The uploader has a manager object that it allocates when it is in the thread. The manager has a QNetworkAccessManager. For every kind of request I do I have a special wrapper which I create that contains the request body and what kind of operation it wants to do. Also, the wrapper has a reference to the QNAM and does the request on it and also catches it when it is finished. Every wrapper object is either a child to the manager, or is allocated in a QScopedPointer.

    Now, I would like to have a cancel button which will abort all the requests and destruct everything in the uploader. When that's done, the thread will be killed. My idea was to, in the wrapper desctructor call "this->_reply->abort()" followed by "this->_reply->deleteLater()". However, this caused me a lot of issue the "abort()" will send a "finished()" signal (which is not stated in the doc) and then I get an access violation. The way it crashes also depends if it is one of the wrappers that are located in a QScopedPointer or as a child to the manager. The issue should be that the QNAM deletes its children (QNetworkReply) since the wrappers take over the parentship of the replies so that they gets deleted with the wrapper.

    So, my question is: if I delete the QNAM object, will all the current calls get aborted? If not, is there another way I could do this? Possible call the manager and tell it to abort all its children and when it's done, delete it.
    Also, how do I handle the "finish()" signal that abort() emits?

    Thanks!

    Edit:

    Had to ad some code showing more what I ment:

    @BaseRequest::~BaseRequest() {
    if(_reply) {
    if(_reply->isRunning()) {
    pantheios::log(pantheios::debug, "BaseRequest(cancel) Request ", _id.toUtf8(), " canceled");
    _reply->abort();
    }
    _reply->deleteLater();
    }
    }@

    When doing this on a QScopedPointer (which gets destroyed in the manager destructor) the stack looks like this:

    @ QtCored4.dll!QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method) Line 2891 + 0xc bytes C++
    QtNetworkd4.dll!QNetworkReplyImpl::abort() Line 874 + 0x18 bytes C++

    FrameworkAzure.dll!BaseRequest::~BaseRequest() Line 126 C++
    FrameworkAzure.dll!PutBlobRequest::~PutBlobRequest() Line 24 + 0x5e bytes C++@

    Where it crashes on line 2891 in QOBject:
    @ const QMetaObject *smeta = sender->metaObject();@

    If however, the wrapper is a child to the manager (not too sure when it gets deleted then) I get this:
    First a warning about "pure virtual function call" and if I click "retry" on the popup I get the following callstack and the message "myapp.exe has triggered a breakpoint"

    @ msvcr100d.dll!_NMSG_WRITE(int rterrnum) Line 217 C
    msvcr100d.dll!_purecall() Line 54 + 0x7 bytes C
    GreenButtonQtFrameworkAzure.dll!BaseRequest::handleFinishedRequest() Line 43 + 0x5 bytes C++
    QtCored4.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3547 + 0x2e bytes C++
    QtNetworkd4.dll!QNetworkReply::finished() Line 166 + 0x13 bytes C++
    QtNetworkd4.dll!QNetworkReplyImplPrivate::finished() Line 796 C++
    QtNetworkd4.dll!QNetworkReplyImpl::abort() Line 887 C++
    @
    If I remove abort() from the destructor I do not get an issue... but does it get aborted? Do not wanna risk it.

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      The abort method aborts any upload in progress, about the finished() signal emitted you could just disconnect it before calling abort()

      @ BaseRequest::~BaseRequest() {
      if(_reply) {
      if(_reply->isRunning()) {
      disconnect(_reply,SIGNAL(finished()),PntToRecivingObject, SLOT(RecivingSlot()));
      pantheios::log(pantheios::debug, "BaseRequest(cancel) Request ", _id.toUtf8(), " canceled");
      _reply->abort();
      }
      _reply->deleteLater();
      }
      }
      @
      obviously you should change PntToRecivingObject and RecivingSlot() whit the corresponding pointer to signal receiver (this maybe?) and slot name

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        that worked perfectly. cant belive i did not do that before. use disconnet() quite a bit.

        thank you :)

        (also, if anyone who writes the doc could actaully state that the abort() also sends a finish() signal, not just cancel() ?)

        1 Reply Last reply
        0
        • C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #4

          You get the finished() signal when the reply is finished, not just finished successfully or finished under your control. When you abort the reply you will almost certainly see the error() signal emitted, with OperationCanceledError, before finished(). Of course, the reply can fail for many other reasons. You should always check that the transfer finished successfully (QNetworkReply::error()) before doing anything that assumes the transfer was successful.

          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #5

            yeah. i surely do that. even parse the reply stream to get error responses aswell as catches every possible qt-error and log it, so that shouldnt be a problem. i just though that the abort() just killed it and that was that. just got a bit confused. read about cancel where they say that it emits a signal, but couldnt see that on the abort() until when i started debugging it and saw it in the call stack. so yeah. really nice to know :)

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              hi again... getting the same issue as before again.

              have a look at this question: http://stackoverflow.com/questions/10440431/abort-reply-crashes-with-access-violation for more info. i have no idea what to do. the disconnect worked some times...

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved