完成另一个方法后立即调用方法

时间:2014-12-01 14:38:55

标签: c++

我将以下伪代码作为C ++项目的一部分:

class BasicSender
{
public:
     virtual void confirmation(int id) = 0;
     int sendMessage(string x)
     {
          Message x = createMessageFromString(x);
          if(! canSendMessage(m))
          {
               MessageStore::storeMessageForLater(this, m); // just store it 
          }
          // *** HERE ***
          return m.messageId;
     }
};

void threadFunction()
{
      while(1)
      {
            while(MessageStore::hasMessagesToBeSent())
            {
                  StoredMessage m = MessageStore.getNextUnsentMessage();
                  if(m.basicSender.sendStoredMessage(m.message))
                  {
                        m.confirmation(m.message.messageId);
                  }
            }
      }
}

及其用法:

class ConcreteSender : public BasicSender
{
    virtual void confirmation(int id)
    {
        cout << "Yippe " << id  << " is sent";
    }
};


int main() {
    ConcreteSender a;
    int ID = a.sendMessage("test");
    ... other stuff
}

我试图实现的目标:

甚至可以在confirmation完成后立即远程调用sendMessage成功传递的消息方法(即:它返回给调用者并且调用者(在main中)具有ID值)。如果我将方法调用放在*** HERE ***的地方,那么虚拟方法将在sendMessage完成之前被调用,并且用户会感到困惑,因为收到的消息ID确认他没有任何线索。是的,我有方法可以检查是否发送了消息,是的,我可以创建一个线程,不时拉MessageStore以查看消息是否已发送。但是我更感兴趣的是,如果有可能以某种方式链接两个函数调用,如果成功:confirmationsendMessage返回后调用。如果有,怎么样? (请注意,我无法修改功能的签名,第三方库:()

1 个答案:

答案 0 :(得分:1)

如果您希望新邮件的ID在main范围内,但您希望它指示实际已发送的邮件的ID,则{{3 }}。一旦main返回,该ID将在sendMessage中可用,但尝试读取其值将阻塞主线程,直到工作线程完成实际发送该消息为止。

这将涉及更改Message以包含承诺,并更改sendMessage以返回引用该承诺的 future

class Message
{
public:
   /*...*/
   std::promise<int> messageIdOnceSent;

private:
   /* ...*/
   int messageId;
};

class BasicSender
{
public:
     virtual void confirmation(int id) = 0;
     std::future<int> sendMessage(string x)
     {
          Message x = createMessageFromString(x);
          if(! canSendMessage(m))
          {
               MessageStore::storeMessageForLater(this, m); // just store it 
          }

          // !!
          return std::future<int>(x.messageIdOnceSent);
     }
};

void threadFunction()
{
      while(1)
      {
            while(MessageStore::hasMessagesToBeSent())
            {
                  StoredMessage m = MessageStore.getNextUnsentMessage();
                  if(m.basicSender.sendStoredMessage(m.message))
                  {
                        m.confirmation(m.message.messageId);

                        // !!
                        m.message.messageIdOnceSent.set_value(m.message.messageId);
                  }
            }
      }
}

int main() {
    ConcreteSender a;
    std::future<int> ID = a.sendMessage("test");

    // !!
    std::cout << ID.get() << '\n'; // blocks until message has actually been sent
}

如果你真的希望ID“紧跟在sendMessage之后”,这是我能得到的最接近的解决方案,而不是在实际发送消息之前。

通常你不想阻止你的主线程,但是如果你的main函数更复杂(并且可能是它),那么这可能就是你要找的。