zoukankan      html  css  js  c++  java
  • 【windows8开发】异步编程 之Concurrency::task(C++)

          从以前的windows应用程序开发转变到Windows8 Metro App开发,如果非要说最需要改变的观念有哪些,显而易见的Metro UI风格大家肯定都认同,而另外一个就是异步处理。从win32早期几乎全盘的同步API,到后来.Net开始支持异步API,微软其实已经做出了API风格上的转变,但是晦涩的回调处理,异常,调试难度让大多数开发者对异步模型开发望而却步,同步处理的观念紧锁住了几乎绝大部分开发者的思想,试问在某些库宣称同时支持同步API和异步API后,包括我自己,又有多少开发者选择去尝试用异步API来构筑他们的应用程序呢?
          如果有公司宣称,“在我的平台上开发App,只要你的应用程序在UI线程上运行超过50ms就会被禁止,你必须把50ms以上的阻塞处理都搬到后台处理。”你可能觉得发表这样言论的人在做梦!但是,这正是windows8告诉我们开发Metro App必须遵循的规则。个人觉得,这个定义虽然会让我们在开发中多少感觉到一点别扭,但却会把windows程序UI操作的用户体验推上一个台阶。
    进入正题,关于win8异步模型,让我们从Concurrency::task这个C++中支持异步API的类开始。
           先看一个例子:
    #include <ppltasks.h>
    #include <iostream>
    using namespace Concurrency;
    using namespace std;
    int main()
    {
        task<int> t([]() {
            return 10;
        });
    
        t.wait();
        wcout << t.get() << endl;
         return 0;
    }
           输出 10

           先解释下这段程序做了什么,task<int>定义了一个并行任务并设定会返回int型值,t的初始化用到了Lambda表达式,其中就涉及到一个异步处理(return 10),wait()会等待异步处理结束,从get()方法能得到异步处理的返回值。这里主要用到了Concurrency::task这个类。
    在异步处理中,经常希望在一个异步操作结束后唤起另外一个异步处理。Concurrency::task也支持这种功能。
    #include <ppltasks.h>
    #include <iostream>
    using namespace Concurrency;
    using namespace std;
    int main()
    {
        task<int> t([]() {
            return 10;
        });
        auto ta =  t.then([](int n){ return n + 10;});
        wcout << ta.get() << endl;
         return 0;
    }
            输出 20

            这里通过then()方法又加了一个异步处理,第一个return返回的10会作为第二个异步处理Lambda匿名函数的参数,get()方法得到n+10的结果。在这里then方法返回的还是task<int>对象,所以如果后续还要追加其他任务可以这样写:
    t.then([]{}).then([]{}).then([]{})..........
          这里通过then()方法追加的延长任务(Continuation task)有Value-Based和Task-Based两种
    // Value-Based:
    t.then([](int n) {});
    // Task-Based:
    t.then([](task<int> preTask) {});

           两者的区别是: Value-Based类型的延长任务在前序任务被取消或发生异常时就不会被执行,而Task-Based类型延长任务则仍旧会被执行。

         怎么样,Concurrency::task的使用很简单吧。但是上面这些其实只是task类的一部分功能,还有很多其他功能,比如任务组合功能Concurrency::when_allConcurrency::when_any,任务延时,任务取消等,本文只是作为一个引子,有兴趣的可以参考微软的MSDN,自己学习吧。
    另外还想说明一点,Concurrency::task的API并不支持来自C++以外语言的调用,所以如果你想封装异步接口的组件供其他语言(JS,C#)调用,就不能使用Concurrency::task直接进行异步操作。针对这种情况Win8还提供了其他的API,我会在下一篇文章中进行说明。其实在前面写的《【windows8开发】C++开发WinRT组件和JS调用》这篇文章中也有关于这方面的内容,JS调用C++组件的实例中就用到了异步处理。
  • 相关阅读:
    linux下实现tomcat定时自动重启
    Mybatis中实现oracle的批量插入、更新
    linux 下ffmpeg和mencoder安装
    jwplayer 源代码重新编译
    如何让android sdk manager飞奔安装sdk
    linux+apache+mod_Jk+tomcat实现tomcat集群
    oracle知识杂记
    Spring Mvc session拦截器实现
    Linux下Tomcat安装、配置
    Linux下安装、配置、授权、调优Mysql
  • 原文地址:https://www.cnblogs.com/secbook/p/2655113.html
Copyright © 2011-2022 走看看