【问题标题】:Asynchronous network calls异步网络调用
【发布时间】:2011-07-31 10:23:44
【问题描述】:

我创建了一个具有异步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

附:所有这些都在 Qt 中完成。

【问题讨论】:

    标签: c++ qt asynchronous


    【解决方案1】:

    如果您尝试使用单个成员变量来维护任意数量的异步操作的状态,那么您将招致各种错误,这就是您在上面描述的内容。您无法确定OpenWebPage 调用完成的顺序,因此也无法将lastAction 在任何给定时间的值与任何特定操作相关联。

    有很多方法可以解决这个问题,例如:

    1. 将网页加载封装在一个不可变类中,每个实例处理一个页面
    2. OpenWebPage 返回一个对象,该对象跟踪进度并存储操作的状态
    3. 在操作完成时触发信号并将操作的上下文附加到信号

    【讨论】:

      【解决方案2】:

      您需要在每个“if”分支的末尾添加“return”语句:在您的代码中,所有“if”分支都在第一个 OnPageLoad 调用中执行。

      一般来说,异步状态管理总是比同步更复杂。考虑用枚举替换 lastAction 类型。另外,如果 OnPageLoad 线程上下文是任意的,则需要同步访问全局变量。

      【讨论】:

      • 是的,呃,这没问题,我这里写的是伪代码,而实际应用中是“else if”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多