[Solved]QNetworkAccessManager and race condition



  • How should I manage the situation when the user click the update button consecutive?

    If I call "get" and update the same container according to the reply
    should I use mutex to protect the container?This is the most easiest solution I
    could think by now, is this a viable solution?Even this work, the user may lose
    the most recently update request.

    The other solution is forbid the user to click "update" button when the data are updating
    How could I allow the user to click the button consecutive like chrome?

    create a queue to store all of the result query by QNetworkAccessManager
    and update the gui by the most recently data?



  • @
    example::example(QWidget parent) : QWidget(parent)
    {
    button = new QPushButton(this);
    connect(button, SIGNAL(clicked()), this, SLOT(request_update()) );
    manager = QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply
    )), this, SLOT(update(QNetworkReplay*)) );
    }
    //.............................................

    void example::request_update()
    {
    manager->get(QNetworkRequest(QUrl(/some url/)));
    }

    void example::update(QNetworkReplay* reply)
    {
    container.push_back(reply->readAll() ); //std::vector<QByteArray>
    }
    @

    some source codes, I hope this could explain what do I want to do better
    Could I encapsulate container with QMutex?Is this solution acceptable?


  • Moderators

    I think a mutex is too much. Plus, a mutex is designed to protect data from being accessed by different threads at the same time... not for preventing a repeated update.

    [quote author="stereomatching" date="1345729738"]The other solution is forbid the user to click "update" button when the data are updating
    How could I allow the user to click the button consecutive like chrome?[/quote]

    I like this solution the best. You can try the code below, just be careful not to make the same connection multiple times:

    @connect(button, SIGNAL(clicked()), this, SLOT(disable_button()) );
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(enable_button()) );

    // ......

    void example::disable_button()
    {
    button->setEnabled(false);
    }

    void example::enable_button()
    {
    button->setEnabled(true);
    }
    @



  • bq. Plus, a mutex is designed to protect data from being accessed by different threads at the same time… not for preventing a repeated update.

    Yap, this is why I haven't use it yet, although QNetworkAccessManager work asynchronous, I'm
    still not sure this is a good solution or not

    bq. You can try the code below

    JKSH, this is the most simple solution I could come up for now
    But my situation is a little bit complicated

    I have a TableView, list a lot of item
    each item could update independently by the same button

    assume I have row0~row3, when I select the row, the situation would become

    row 0 press -> disable the update button
    row 1 hasn't pressed ->enable the update button
    row 2 press -> disable the update button

    The other solution is don't disable the button, but disable the "row"(data of the table model)
    But I can't find a function to disable the the row of the TableView
    maybe need to design a delegate to do that


  • Moderators

    I see. How about this:

    Have a flag for every row, such as "QVector<bool> rowIsUpdating" where rowIsUpdating.size() == TOTAL_NUMBER_OF_ROWS

    When the user updates row i, set rowIsUpdating[i] = true; and then when the update finishes, set rowIsUpdating[i] = false

    Every time the button is clicked, the program checks rowIsUpdating[i] before calling manager->get()

    @void example::request_update(int row)
    {
    if (!rowIsUpdating[row])
    {
    rowIsUpdating[row] = true;
    manager->get(QNetworkRequest(QUrl(/some url/)));
    }
    }
    @



  • Sounds like a good idea, I will give it a try, thanks



  • The probelm become more complicated
    Every row have several columns
    And I have to implement sorting fucntion
    That means I have to create many flags for those model items
    else I have no way to know when will those items updated

    network programming is pretty comlicated even with the help of
    high level API like QtNetwork provide.


  • Moderators

    [quote author="stereomatching" date="1345902275"]The probelm become more complicated
    Every row have several columns
    And I have to implement sorting fucntion
    That means I have to create many flags for those model items
    else I have no way to know when will those items updated[/quote]Sounds like you have a solution, at least. Good luck!

    [quote author="stereomatching" date="1345902275"]
    network programming is pretty comlicated even with the help of
    high level API like QtNetwork provide.[/quote]You have a User Interface problem or a State Machine problem. Not a networking problem.



  • bq. You have a User Interface problem or a State Machine problem. Not a networking problem.

    Thanks, you give me a new direction, I should study state machine
    maybe it could may my codes easier to maintain


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.