基于任务编程

2017-02-09  本文已影响50人  龙翱天际

基于任务编程

在卡萨布兰卡中,所有长时间运行或有可能阻塞的API都是异步的,例如:任何网络请求的API。PPL任务用于表示一些异步任务的完成。为了让卡萨布兰卡在VS2010和其他非windows平台也能使用,我们创建了一个特别版本的PPL任务并把它包含在卡萨布兰卡中。为了让它和PPL和平共处,我们把该版本命名为pplx
一个基于任务的操作可能会也可能不会立即结束。例如:当发送一个HTTP消息是,我们最后将得到一个消息响应。任务最后可得到这样的响应:

web::http::client::http_client client(U("http://localhost:80"));
pplx::task<web::http::http_response> resp = client.request(web::http::methods::GET, U("/foo.html"));

在这儿,任务resp为我们提供了一个将来会用到的值的占位符。只要你有一个任务,实际上,你就需要从这个任务中得到这个值。因为有可能操作完成的很快,任务所绑定的值很快就变得有效,所以有时候我们会去询问任务是否已经完成:

bool done = resp.is_done();

is_dong()返回true的时候,我们再用get()方法去取值,可以确保操作不会block(阻塞):

web::http::http_response response = resp.get(); 

如果is_done()返回false,调用'get()'将会导致阻塞线程,这样也就违背了在开始的位置使用异步API目的(保持GUI刷新和服务扩展)。对于这种情况,我们需要采取另外的途径:为任务绑定一个处理器函数,该函数在任务一结束时,就会被调用。我们使用then()函数:

resp.then([=] (web::http::http_response  response)
{
   ...
}); 

传递给一个任务的then()函数对象应该传入一个T或任务的参数:

resp.then([=](pplx::task<web::http::http_response> task)
{
    web::http::http_response  response = task.get();
    ...
}); 

因为我们知道任务已经完成,在回调函数里里调用get()绝对不会导致阻塞。

上一篇下一篇

猜你喜欢

热点阅读