异步函数 活动对象

1.SymbianOS是基于客户/服务架构的,高度异步的操作系统,它提供一些运行于独立进程的服务,具有高度的可靠性.

   多数情况下,应用程序只使用到OS本身提供的某些系统功能.

   服务器API提供的函数一般有同步和异步版本,为了避免一些耗时的操作阻塞应用程序的接口,一般使用异步版本.

  

2.异步函数将iStatus的值设为KRequestPending后立即返回,它们在后台的单独线程中执行,这样与调用程序并行执行,当异步函数执行完后,向调用程序发送一个事件,然后一般去执行回调函数,若调用程序未执行完毕,则回调函数要等调用程序执行完才被执行.

3.调用程序使用User::WaitForRequest()来等待调用线程拥有的请求信号量被通知,即阻塞调用程序,来等待异步函数完成。

 

4.为了方便允许应用程序发布多个异步请求,并且在任何当前请求完成时获得通知,SymbianOS提供了一个支持框架:通过实现两种类型的对象来完成协作式多任务

(1)用于等待循环的活动规划器--每个线程一个活动规划器(提供的静态函数总是引用当前活动规划器)

(2)用于每个任务的活动对象--该对象封装异步请求及对象的处理函数.

5.活动对象是调用异步函数的类,它封装了异步服务请求,通过回调来处理异步函数的完成.它是一种处理实现类似多线程工作方式的机制.

6.使用活动对象的线程包含多个活动对象和一个活动调度器CActiveScheduler。调度器实现一个事件循环,它等待线程的请求信号量。当接收到某个事件时,会调用该事件所属活动对象的RunL方法。在Gui应用程序中,使用活动对象的线程已经安装了一个活动调度器。

7.活动调度器的等待循环及其活动对象的RunL方法被调用,都在同一线程中发生,实现了所谓的非抢占式多任务处理。

8.游离的信号异常,即调度器得到信号量通知,却未找到一个符合要求的活动对象来处理事件。

9.函数Cancel()检查活动对象是否有未完成的请求,如果有,就调用覆盖的函数DoCancel(),如果没有,就不调用。当DoCancel()方法退出后,Cancel()方法会调用User::WaitForRequest()方法(把信号标记量减1),即销毁KErrCancel消息.

 

10.什么时候使用活动对象?

     当需要使用到系统提供的异步服务 或需要当前回调函数执行完后才能执行另一个请求而使用时间等待异步时

     这时需要使用活动对象来封装异步请求.

      在多个异步函数中处理事件,或通过非抢占式方式实行多个线程,使用活动对象是最好的方式.

11.symbian里不是所有的异步函数都可以使用User::WaitForRequest转换为同步, 比如如果该函数的实现里又请求了异步函数, 它的实现在RunL里才提交对你的事件, 使用User::WaitForRequest阻碍了RunL的调用, 导致程序挂死, 无法正常运行.
可以使用CActiveScheduleWait来实现伪同步,该类内部共用了活动规划期的AO列表, 使用自己的事件循环队列, 唯一的问题是在退出时的表现不完美.

 

12.CActiveScheduler::Start();

    .......

你可能感兴趣的:(Symbian)