六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 38|回复: 0

深入活动对象1

[复制链接]

升级  30%

3

主题

3

主题

3

主题

童生

Rank: 1

积分
15
 楼主| 发表于 2013-1-15 02:57:49 | 显示全部楼层 |阅读模式
转自杨芹勍《活动对象正解(1)-理解活动对象》
 
Symbian OS中的活动对象的使用无疑是最基础的、最频繁的、最重要的。什么是活动对象呢?
大家学习一个新的事物时,总是会将这个新的事物与自己认知的事物相比较,从而达到快速学习的目的。我开始学习Symbian的时候,我查看很多Symbian书籍、网上很多Symbian教程都将活动对象与多线程联系到一起,我也总是会把活动对象想象成一个线程。然而,经过了更深入的接触,我发现并不像我想象的那样。
现在,我在此向你保证:活动对象和多线程没有任何关系!不要拿平时做多线程的思想去理解活动对象!
活动对象可以按照以下步骤这么理解:

  • Symbian OS中提供了很多异步函数,这些异步函数大多部分都是基于“服务器-客户端”架构的。这里与win32 api中的函数有很大的不同。如:
    win32中,CSocket::Receive(是recv而不是WSARecv)为同步函数,线程阻塞在Receive处,直到套接字接收到了网络流才返回
    Symbian OS也有类似的函数,RSocket::Receive,但是此函数是一个异步函数,线程不会阻塞在Receive处而会继续执行。  
  • 如何区分Symbian中的函数哪些是同步的哪些是异步的?很简单:看函数内是否包含类型为TRequestStatus的形参,如果有则函数为异步函数。如RSocket::Receive的函数原型为:IMPORT_C void Recv(TDes8 &aDesc, TUint flags, TRequestStatus &aStatus);  
  • 参数aStatus为一个状态位,初始值为ERequestPending(值为1),它意味着用户请求的操作是否执行完毕。如:我们调用异步函数RSocket::Receive请求接收网络流,Receive函数会直接返回。当“接收”网络流的过程完毕后,aStatus会变为EActive,所以我们只要监视aStatus是否不为ERequestPending就可以知道“接收”是否完成了。
  • 我们可以使用以下伪代码完成以上所述操作:
    TRequestStatus status(KRequestPending);RSocket::Receive(aDesc, flags, status);for (;;){if (status != KRequestPending) break;}// 此处我们已经通过RSocket::Receive完成了类似CSocket::Receive的同步的工作
  • Symbian OS不建议我们使用以上方法,它建议我们使用异步方法,而不要使用我们这种方法去强制同步,活动对象就是帮我们做这件事情。活动对象体系帮我们监视aStatus的值,只要aStatus != ERequestPending,他就会以事件的方式通知我们,告诉我们“Socket已经接收完毕,你可以去取数据了!”,活动对象就是干这事的。
  • 总结一下:系统中有一个“活动调度器”,我们建立一个“活动对象ao1”,将该对象与某个系统中的异步函数绑定,然后将该活动对象注册到“活动调度器”中,“活动调度器”会等待异步函数返回的“完成”消息。收到完成消息后,调度器遍历所注册的活动对象,如果发现status !=KRequestPending则找到该status对应的“活动对象ao1”,调用其中的RunL方法,以事件的方式告知我们异步函数已经执行完成。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表