C++ 在重构之后,异步调用方法不再有效
为了将GUI与逻辑(从REST服务获取数据)分离,我将一些逻辑重构为控制器 现在,似乎只有部分逻辑起作用 重构后的GUI组件看起来是这样的(我使用的是JUCE框架) GUI控制器如下所示:C++ 在重构之后,异步调用方法不再有效,c++,asynchronous,boost,future,juce,C++,Asynchronous,Boost,Future,Juce,为了将GUI与逻辑(从REST服务获取数据)分离,我将一些逻辑重构为控制器 现在,似乎只有部分逻辑起作用 重构后的GUI组件看起来是这样的(我使用的是JUCE框架) GUI控制器如下所示: #define BOOST_THREAD_PROVIDES_FUTURE #include "../includes/ProjectEntryListController.h" template<typename R> bool isReady(std::future<R> cons
#define BOOST_THREAD_PROVIDES_FUTURE
#include "../includes/ProjectEntryListController.h"
template<typename R>
bool isReady(std::future<R> const& f)
{
Logger::writeToLog("check future");
return f.wait_for(std::chrono::seconds(-1)) == std::future_status::ready;
}
ProjectEntryListController::ProjectEntryListController(ProjectEntryListComponent *comp) {
m_comp = comp;
requestProjects();
}
void ProjectEntryListController::requestProjects()
{
Logger::writeToLog("requesting projects");
projectsFuture = std::async(std::launch::async, &ProjectsController::getProjects, &pc);
Logger::writeToLog("requested projects");
}
void ProjectEntryListController::backgroundCheckFuture()
{
timer = new boost::asio::deadline_timer(io_service, boost::posix_time::seconds(interval_secs));
timer->async_wait(boost::bind(&ProjectEntryListController::fetchData, this, boost::asio::placeholders::error, timer));
ioSvcFuture = std::async(std::launch::async, static_cast<size_t(boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service);
}
void ProjectEntryListController::initData() {
requestProjects();
backgroundCheckFuture();
}
void ProjectEntryListController::fetchData(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* tmr) {
if (isReady(projectsFuture)) {
projects = projectsFuture.get();
for (auto project : projects)
{
ProjectEntryComponent *pec = new ProjectEntryComponent(std::to_string(project.getId()), "222");
m_comp->addListEntry(pec);
m_comp->repaint();
}
Logger::writeToLog("got projs");
}
else {
tmr->expires_at(tmr->expires_at() + boost::posix_time::seconds(interval_secs));
tmr->async_wait(boost::bind(&ProjectEntryListController::fetchData, this, boost::asio::placeholders::error, tmr));
}
}
但是,当我调试到代码中时,调试器(使用VS 2015)也能够单步执行日志消息
我做错了什么?事实上我现在解决了这个问题 1.)我调用了错误的方法
requestProjects
,而不是initData
2.)我无法看到结果,因为缺少ProjectEntryComponent::ProjectEntryComponent(std::string name,std::string version)
的实现
#define BOOST_THREAD_PROVIDES_FUTURE
#include "../includes/ProjectEntryListController.h"
template<typename R>
bool isReady(std::future<R> const& f)
{
Logger::writeToLog("check future");
return f.wait_for(std::chrono::seconds(-1)) == std::future_status::ready;
}
ProjectEntryListController::ProjectEntryListController(ProjectEntryListComponent *comp) {
m_comp = comp;
requestProjects();
}
void ProjectEntryListController::requestProjects()
{
Logger::writeToLog("requesting projects");
projectsFuture = std::async(std::launch::async, &ProjectsController::getProjects, &pc);
Logger::writeToLog("requested projects");
}
void ProjectEntryListController::backgroundCheckFuture()
{
timer = new boost::asio::deadline_timer(io_service, boost::posix_time::seconds(interval_secs));
timer->async_wait(boost::bind(&ProjectEntryListController::fetchData, this, boost::asio::placeholders::error, timer));
ioSvcFuture = std::async(std::launch::async, static_cast<size_t(boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service);
}
void ProjectEntryListController::initData() {
requestProjects();
backgroundCheckFuture();
}
void ProjectEntryListController::fetchData(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* tmr) {
if (isReady(projectsFuture)) {
projects = projectsFuture.get();
for (auto project : projects)
{
ProjectEntryComponent *pec = new ProjectEntryComponent(std::to_string(project.getId()), "222");
m_comp->addListEntry(pec);
m_comp->repaint();
}
Logger::writeToLog("got projs");
}
else {
tmr->expires_at(tmr->expires_at() + boost::posix_time::seconds(interval_secs));
tmr->async_wait(boost::bind(&ProjectEntryListController::fetchData, this, boost::asio::placeholders::error, tmr));
}
}
std::vector<Project> ProjectsController::getProjects() {
std::vector<Project> result;
if(serviceClient != nullptr) {
try
{
std::this_thread::sleep_for(std::chrono::seconds());
std::cout << "controller requested projs\n";
result = serviceClient->getAvailableProjects();
}
catch (const std::exception&)
{
}
}
return result;
}