Windows8开发】异步编程进阶篇之 create_async, create_task, make_task区别与联系

Windows8开发】异步编程进阶篇之 create_async, create_task, make_task区别与联系

分类: window8 App开发   842人阅读  评论(3)  收藏  举报
create_async, create_task, make_task都是WinRT下为异步编程服务的API,它们之间有何联系,又有何区别呢?

create_async是为跨语言调用服务的,也就是说如果希望封装的方法可以被C++以外语言的组件调用,那就需要create_async来创建异步处理,那除了这点外,它与create_task在实际应用中还有什么区别与联系呢?
首先是返回值。create_async基于跨语言的考虑返回4种支持个语言平台间通用的异步处理接口:
1. Windows::Foundation::IAsyncAction : 无返回值,无处理进度报告
2. Windows::Foundation::IAsyncActionWithProgress<TProgress>:无返回值,有处理进度报告
3. Windows::Foundation::IAsyncOperation<TResult>:有返回值,无处理进度报告
4. Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>:有返回值,有处理进度报告

而create_task则返回Concurrency::task<TRESULT>对象,看如下示例:
[cpp]  view plain copy
  1. task<int> op1 = create_task([]()  
  2. {  
  3.      return 0;  
  4. });  
  5.   
  6. IAsyncOperation<int>^ op2 = create_async([]()  
  7. {  
  8.      return 0;  
  9. });  

两者都可以使用auto关键字来处理返回值
[cpp]  view plain copy
  1. auto op1 = create_task([]()  
  2. {  
  3.      return 0;  
  4. });  
  5. auto op2 = create_async([]()  
  6. {  
  7.      return 0;  
  8. });  

Concurrency::task可以很方便的使用then方法来处理异步处理间的延续异步任务调用(task continuation),如上面的处理中,可以如下使用then方法:
[cpp]  view plain copy
  1. op1.then([](int v){  
  2.      return 0;  
  3. });  

那如果create_async创建的异步处理在C++中如何实现task continuation?很简单,其实create_task的参数可以是IAsyncAction等4种异步处理接口,所以结合create_task就可以这样来使用:
[cpp]  view plain copy
  1. create_task(op2).then([](int v){  
  2.      return 0;  
  3. });  

那如果是在C++以外的语言中调用create_async封装的C++方法,如何实现then类似的功能呢?因为这不是本文讨论的重点,只简单说明下,C#中可以通过async和await关键字来控制;而js中也通过了类似的then方法来实现,请参考【windows8开发】C++开发WinRT组件和JS调用一文。
create_task是WinRT提供的一个便于创建task的API,其实通过直接构建task<TRESULT>对象也可以实现一样的目的:
[cpp]  view plain copy
  1. task<int> op1([]()  
  2. {  
  3.      return 0;  
  4. });  

既然说到了task和then,顺便介绍个概念,Value-Based和Task-Based。看下面的例子:
[cpp]  view plain copy
  1. create_task([]()  
  2. {  
  3.      return 0;  
  4. }).then([](int x)  
  5. {  
  6.      return x;  
  7. });  

首先要明白第一个Lambda表达式的return值会作为第二个then中Lambda表达式匿名函数的参数。而如上这种写法是Value-Based的。那Task-Based呢?写法上有一点区别,就是第二个Lambda表达式的参数变成了task<int>类型。
[cpp]  view plain copy
  1. create_task([]()  
  2. {  
  3.      return 0;  
  4. }).then([](task<int> pretask)  
  5. {  
  6.      return pretask.get();  
  7. });  

那实际功能上的区别呢?当你希望前任务发生异常或某些情况下被cancel时,后序任务仍旧能够正常执行,那就应该使用Task-Based的形式,而反之,则使用Value-Based,后序的任务将不会被执行。当然期间会涉及到一些处理细节,会在后续介绍异步编程任务取消机制、异常处理等概念时再详细说明。

最后再来说说make_task。其实make_task跟前两者没有直接的联系,它是用来创建某个任务组(task group)中的单个任务的,在使用concurrency::structured_task_group时,会通过make_task来创建每个任务的任务句柄(task handle),然后再把这些任务句柄添加到任务组中。看个make_task的简单例子:
[cpp]  view plain copy
  1. // Create a task group that serves as the root of the tree.  
  2. structured_task_group tgroup;  
  3.   
  4. // Create a child task.  
  5. auto task1 = make_task([&] {  
  6.     // TODO: Perform work here.  
  7. });  
  8.   
  9. // Create a child task.  
  10. auto task2 = make_task([&] {  
  11.     // TODO: Perform work here.  
  12. });  
  13.   
  14. // Run the child tasks and wait for them to finish.  
  15. tgroup.run(task1);  
  16. tgroup.run(task2);  
  17. tgroup.wait();  

在后续介绍任务组的部分会再详细说明make_task,这里只是简单提一下,知道它跟create_task完全不是一回事就可以了,
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值