WApplication :: bind()用法与Wt :: WServer :: post

时间:2015-09-22 13:36:51

标签: wt

我想绑定一个回调,它将被Wt事件循环外的一个线程调用。 显然我想使用Wt :: WServer :: post,但我不知道如何使用WApplication :: bind,因为它是一个非静态函数。 第一次尝试是这样的:

auto loaded_callback = [](const decltype(Wt::WApplication::sessionId) &session){
    Wt::WServer::post(session, 
Wt::WApplication::bind(&table_model::member_func),)
};

当然,这不起作用,因为bind是非静态的。但是我的下一次尝试

auto object_protect_bind = 
Wt::WApplication::instance()->bind(&order_aggregate_table_model::load_future_in_map);

发生错误的编译器错误

  

错误153错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int \ boost \ function \ function_template.hpp 922 1 MDDB_Web   错误156错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int \ boost \ function \ function_template.hpp 926 1 MDDB_Web   错误160错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int \ boost \ function \ function_template.hpp 927 1 MDDB_Web   错误150错误C2903:'apply':符号既不是类模板也不是函数模板\ boost \ function \ function_template.hpp 922 1 MDDB_Web   错误162错误C2825:'manager_type':必须是一个类或命名空间,后跟'::'\ boost \ function \ function_template.hpp 934 1 MDDB_Web   错误154错误C2653:'handler_type':不是类或命名空间名称\ boost \ function \ function_template.hpp 926 1 MDDB_Web   错误158错误C2653:'handler_type':不是类或命名空间名称\ boost \ function \ function_template.hpp 927 1 MDDB_Web   错误164错误C2275:'manager_type':非法使用此类型作为表达式\ boost \ function \ function_template.hpp 934 1 MDDB_Web   错误165错误C2146:语法错误:在标识符'manage'\ boost \ function \ function_template.hpp之前缺少'}'934 1 MDDB_Web   错误159错误C2146:语法错误:缺少';'在标识符'manager_type'之前\ boost \ function \ function_template.hpp 927 1 MDDB_Web   错误155错误C2146:语法错误:缺少';'在标识符'invoker_type'之前\ boost \ function \ function_template.hpp 926 1 MDDB_Web   错误152错误C2143:语法错误:缺少';'在'<'之前\ boost \ function \ function_template.hpp 922 1 MDDB_Web   错误163错误C2039:'manage':不是'`global namespace''\ boost \ function \ function_template.hpp的成员934 1 MDDB_Web   错误151错误C2039:'apply':不是'boost :: detail :: function :: get_invoker0'的成员\ boost \ function \ function_template.hpp 922 1 MDDB_Web   错误166错误C1903:无法从先前的错误中恢复;停止编译\ boost \ function \ function_template.hpp 934 1 MDDB_Web

虽然我想到的整体解决方案是:

auto sessionId = Wt::WApplication::instance()->sessionId();
auto server_ptr = Wt::WServer::instance();

auto object_protect_bind = Wt::WApplication::instance()->bind(&order_aggregate_table_model::load_future_in_map);
auto inner_bind = std::bind(object_protect_bind, this);
auto loaded_callback = [] 
    (Wt::WServer* server,
    const std::string &session,
    boost::function<void()> widget_bind)
-> void {
    server->post(session, widget_bind, boost::function<void()>());
};

this->data_future =
    std::async(std::launch::async,
    table_model::load_quiet_a_bunch_of_data,
    query, database, std::bind(loaded_callback, server_ptr, sessionId, inner_bind));
Wt::WTimer::singleShot(20 * 1000, this, &table_model::load_future_in_map);

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

感谢Koen Deforche in the official forum,问题是:  Wt::WApplication::bind应该采用已绑定的方法,而不是方法本身。

使用lambdas时,还有一个令人惊讶的(至少对我来说)模板细节,所以为了一个例子,我的数据加载线程使用的回调解决方案是:

static std::map<decltype(views::measurements_grouped_by_orders::order_number),
    order_value> 
    order_aggregate_table_model::async_load_order_values(
    const odb::query<views::measurements_grouped_by_orders> &query,
    std::shared_ptr<odb::database> mddb,
    std::function<void(void)> callback) {...
    if (callback){ callback(); }
    return map;
    }

void order_aggregate_table_model::get_data(const odb::query<views::measurements_grouped_by_orders> &query){

auto sessionId = Wt::WApplication::instance()->sessionId();
auto server_ptr = Wt::WServer::instance();

auto object_protect_bind = 
    Wt::WApplication::instance()->bind(/*Wt::WApplication::bind
                                       handles the case that 
                                       the widget might already been destroyed*/
        std::bind(&order_aggregate_table_model::load_future_in_map,this));
auto loaded_callback = [] 
    (Wt::WServer* server,
    const std::string &session,
    std::function<void()> widget_bind)
-> void {
    server->post(session, widget_bind, boost::function<void()>()); 
    //Wt::Server::post handles the case when the session is already been destroyed
};
std::function<void()> final_callback = //Because of template quirks had to stick the type
    std::bind(loaded_callback, server_ptr, sessionId, object_protect_bind);
this->order_aggregate_map_future =
    std::async(std::launch::async,
    order_aggregate_table_model::async_load_order_values,
    query, this->mddb, final_callback);

Wt::WTimer::singleShot(30 * 1000, this, 
    &order_aggregate_table_model::load_future_in_map); //For the case that the async loader crashed
    }