利用CActiveSchedulerWait 将异步操作转换为同步

    最近接手了公司的手机游戏工作,其中一部分是基于Symbian平台开发的应用和游戏,于是开始学习相关的开发。由于时间的紧迫性,没有办法从头一章一章的学习,所以还是采用了源码+google的方法来学习,这部分的内容会比较散,但先记下来吧。
    以下是关于CActiveSchedulerWait操作的文章,转载如下:


最近看Liuxg的IMEI示例,终于把CActiveSchedulerWait稍微搞明白了一点,赶快记录下来,否则过一阵又要忘了。

总的来说,CActiveSchedulerWait应该用在某个活动对象中,目的是把某个异步操作转换为同步操作。以获取IMEI为例:
class CImeiEngine : public CActive
CImeiEngine是一个活动对象,获取IMEI的核心操作是一个异步操作,看如下代码:
void CImeiEngine::GetImei()
{
if ( IsActive() )
{
Cancel();
}

CTelephony::TPhoneIdV1Pckg phoneIdPckg( iPhoneId );
iTelephony->GetPhoneId( iStatus, phoneIdPckg );

SetActive();
StartWait();
}
我们就是通过CTelephony::GetPhoneId来获取IMEI号的,但是我们在实际使用中,最好将CImeiEngine::GetImei方法做成同步的,这样最方便。设想一下调用流程:
iImeiEngine->GetImei(); //iImeiEngine是一个CImeiEngine实例
DoSomeThingWithImei(); //此时IMEI号肯定已经获取成功

为了保证以上的同步调用正常工作,GetImei()必须是一个同步方法,这就是需要使用CActiveSchedulerWait的原因。
看一下CImeiEngine::StartWait的实现:
void CImeiEngine::StartWait( )
{
if ( iWait.IsStarted() != (TInt)ETrue )
{
iWait.Start();
}
}
代码相当简单,就是调用了CActiveSchedulerWait::Start方法而已。
程序运行到CImeiEngine::GetImei中的StartWait()这行代码后,将会一直阻塞(实际上是阻塞在iWait.Start()这一行),直到CImeiEngine::RunL被调用:
void CImeiEngine::RunL()
{
iWait.AsyncStop();

if ( iStatus == KErrNone )
{
// The request is successful
TBuf manufacturer = iPhoneId.iManufacturer;
TBuf model = iPhoneId.iModel;
TBuf serialNumber = iPhoneId.iSerialNumber;

if ( iObserver )
{
CTelephony::TPhoneIdV1Pckg phoneIdPckg( iPhoneId );
iObserver->UpdatePhoneInfo( serialNumber );
}
}
}
在RunL中,首先调用iWait.AsyncStop()这会导致CActiveSchedulerWait结束等待,也就是回到 iWait.Start()之后。但是因为活动对象的特殊性,走完iWait.AsyncStop()这步并不会立刻返回到iWait.Start(), 而是在RunL走完才会返回,所以没有必要将iWait.AsyncStop()放到RunL函数的末尾。
这样,CImeiEngine::GetImei就被设计成为一个同步方法了。

将异步转换为同步,还可以使用User::WaitForRequest方法,但是据说有些情况下无法正常工作,这个方法会一直挂起,我倒是没有机会遇到这种情况。

题外话:
为了获取IMEI号,也可以不将GetImei设计为同步方法,这样就避免了使用CActiveSchedulerWait。这样做需要尽可能早地执行 CTelephoy::GetPhoneId,并把获取到的IMEI号保存起来,在使用IMEI号前还需要判断是否已经成功获取。无论如何,这种方案都没 有同步获取来得安全。

附注:
以上示例中,iWait是CImeiEngine的一个成员对象:
class CImeiEngine : public CActive
{

private:
CActiveSchedulerWait iWait;

}
iWait作为CImeiEngine的一个成员变量,在CImeiEngine初始化完成之后就已经被构造,所以无须手工构造及释放。

     原文地址:http://coastline.freepgs.com/?p=14
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值