我将以下伪代码作为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
以查看消息是否已发送。但是我更感兴趣的是,如果有可能以某种方式链接两个函数调用,如果成功:confirmation
在sendMessage
返回后调用。如果有,怎么样? (请注意,我无法修改功能的签名,第三方库:()
答案 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
函数更复杂(并且可能是它),那么这可能就是你要找的。 p>