返回类型的回调函数

问题描述:

方法“DataOperation”必须返回DataResponse类型中的值。返回类型的回调函数

我在我的异步请求回复“LoadDataReply”里面有一个回调函数,在这个回调函数中,我在收到的回复中应用了一些业务逻辑并返回主方法(我不确定返回回调是否正确)。

你们可以帮我介绍如何为LoadData方法的调用者返回值。

DataResponse DataOperation::LoadData(const RequestType request) 
{ 
DataResponse dataResponse; 
messageAssistant.AsyncRequest("LoadDataList", request) 
    .OnReply<MyResponseType>("LoadDataListReply", [this, &dataResponse](auto& reply) { dataResponse = this->LoadDataFromResponse(reply); }); 

return dataResponse; 
} 

DataResponse DataOperation::LoadDataFromResponse(const MyResponseType& reply) 
{ 
    ///Doing some operation with reply data 
    DataResponse dataResponse; 
    dataResponse.Data = reply.Data(); 
    return dataResponse; 
} 

上面的代码没有编译。

我收到编译错误,

error C4716: 'DataOperation::LoadData': must return a value 

注: -我已经更新了我的代码,并编译没有任何问题。但是,我从LoadData返回的dataResponse对象最终没有在LoadDataFromResponse中更新值。它具有初始值。

我怎样才能确保它返回更新后的值而不是初始值?

+0

你不会在那里返回任何价值? –

+0

我需要将dataResponse返回给LoadData方法的调用方。 – Joe

+1

@Joe那么,'返回'呢? 'LoadData'是非void函数,但它没有'return'语句,这反过来就意味着这样的程序的行为是不确定的。 –

这已通过回调修复。

使用处理程序。你可以创建Handler(每个线程可以访问的消息列表)。看看pseodocode下面:

class Handler { 
public: 
    Handler(); 
    // Constructor 
    ~Handler(); 
    // Destructor 
    void pushmessage (DataResponse* p); 
    DataResponse* popmessage(); 
    bool empty(); 
protected: 
    vector<DataResponse*> pool; 
    RTTICriticalSection CS; 
}; 

Handler::Handler() 
{ 
    CS = CreateCriticalSection; 
} 

Handler::~Handler() 
{ 
    DeleteCriticalSection(CS); 
} 

void Handler::pushmessage (DataResponse* p) 
{ 
    EnterCriticalSection(CS); 
    try { 
    pool.push_back(p) 
    } catch(...){ 
    // 
    } 
    LeaveCriticalSection(CS); 
} 

DataResponse* Handler::popmessage() { 
    DataResponse* dr = null; 
    EnterCriticalSection(CS); 
    try { 
    dr = pool.back(); 
    pool.pop_back(); 
    } catch(...){ 
    // 
    } 
    LeaveCriticalSection(CS);  
    return dr; 
} 

bool Handler::empty() { 
    bool res = true; 
    EnterCriticalSection(CS); 
    try { 
    res = pool.empty(); 
    } catch(...){ 
    // 
    } 
    LeaveCriticalSection(CS);  
    return res;  
} 

DataResponse DataOperation::LoadData(const RequestType request) 
{ 
    messageAssistant.AsyncRequest("LoadDataList", request) 
    .OnReply<MyResponseType>("LoadDataListReply", [this](auto& reply) { this->LoadDataFromResponse(reply); }); 
} 

/*DataResponse* */ void DataOperation::LoadDataFromResponse(const MyResponseType& reply) 
{ 
    ///Doing some operation with reply data 
    DataResponse* dataResponse = new DataResponse(); 
    dataResponse.Data = reply.Data(); 
    handler.pushmessage(dataResponse); 
    //return dataResponse; 
} 

//call this sub somewhere inside the idle cycle synchronized with the main thread 
void proceedMessages() { 
    while (!handler.empty()) 
    { 
    DataResponse* dr = handler.popmessage(); 
    //do something with dr 
    //free dr 
    } 
}