Асинхронные сетевые вызовы - PullRequest
2 голосов
/ 31 июля 2011

Я создал класс с асинхронной функцией OpenWebPage(). Как только вы вызываете OpenWebPage(someUrl), вызывается обработчик - OnPageLoad(reply). Я использовал глобальную переменную под названием lastAction, чтобы заботиться о вещах после загрузки страницы - обработчик проверяет, что такое lastAction, и вызывает соответствующую функцию. Например:

this->lastAction == "homepage";
this->OpenWebPage("http://www.hardwarebase.net");

void OnPageLoad(reply)
{
     if(this->lastAction == "homepage")
     {
         this->lastAction = "login";
         this->Login();     // POSTs a form and OnPageLoad gets called again
     }
     else if(this->lastAction == "login")
     {
         this->PostLogin(); // Checks did we log in properly, sets lastAction as new topic and goes to new topic URL
     }
     else if(this->lastAction == "new topic")
     {
         this->WriteTopic(); // Does some more stuff ... you get the point
     }
}

Теперь, это довольно сложно писать и отслеживать, когда у нас большое количество "действий". Когда я делал вещи на Python (синхронно), это было намного проще, например:

OpenWebPage("http://hardwarebase.net") // Stores the loaded page HTML in self.page
OpenWebpage("http://hardwarebase.net/login", {"user": username, "pw": password}) // POSTs a form
if(self.page == ...): // now do some more checks etc.
    // do something more

Теперь представьте, что у меня есть класс очереди, который содержит действия: домашняя страница, вход в систему, новая тема. Как я должен выполнить все эти действия (в правильном порядке, один за другим!) Через асинхронный обратный вызов? Первый пример явно жестко запрограммирован.

Надеюсь, вы понимаете мой вопрос, потому что, честно говоря, я боюсь, что это худший вопрос, когда-либо написанный: x

P.S. Все это сделано в Qt.

Ответы [ 2 ]

1 голос
/ 31 июля 2011

Вы предлагаете всевозможные ошибки, если вы пытаетесь использовать одну переменную-член для поддержания состояния для произвольного числа асинхронных операций, что вы и описали выше. Вы не можете определить порядок выполнения вызовов OpenWebPage, поэтому также невозможно связать значение lastAction в любой момент времени с какой-либо конкретной операцией.

Есть несколько способов решить эту проблему, например:

  1. Инкапсуляция загрузки веб-страниц в неизменяемый класс, который обрабатывает одну страницу на экземпляр
  2. Возвращает объект из OpenWebPage, который отслеживает прогресс и сохраняет состояние операции
  3. Запустить сигнал после завершения операции и присоединить к сигналу контекст операции
1 голос
/ 31 июля 2011

Вы должны добавить оператор return в конце каждой ветви if: в вашем коде все ветви if выполняются при первом вызове OnPageLoad.

Как правило, асинхронное распределение состояний всегда сложнее, чем синхронное. Попробуйте заменить тип lastAction перечислением. Кроме того, если контекст потока OnPageLoad является произвольным, вам необходимо синхронизировать доступ к глобальным переменным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...