Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1540804
  • 博文数量: 237
  • 博客积分: 5139
  • 博客等级: 大校
  • 技术积分: 2751
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-18 14:48
文章分类

全部博文(237)

文章存档

2016年(1)

2012年(4)

2011年(120)

2010年(36)

2009年(64)

2008年(12)

分类: C/C++

2009-11-23 12:51:06

在symbian中,AO(活动对象)承当了重要的角色,它可以完成多任务以及众多异步操作,理论上,它是可以完全替代一般系统中的多线程的,

但symbian还是为我们保留了多线程,实际上,在有些情况下,我们还是需要多线程的。如有的很复杂的递归过程不能拆解为AO,那我们就只能用多线程了。

使 用多线程时,我们要注意的异常退出时的处理,如用户在后台任务正在执行时按下退出键,这个时候我们处理要得当,一般是要调用Cancel()函数来处理 的,就实际编码来说,我们一般在一个AO中处理多线程,因为symbian中的多线程通知机制是用活动对象来完成的,我们调用 RThread::Logon(iStatus)来将iStatus设置为KRequestPending,以便使用完成请求来通知线程的完成,那如果线 程意外中断的话,我们就可以调用Cancel()来处理,我们应该总是在DoCancel()函数的重载中完成线程的中断和关闭,如:
RThread thread ;
thread.Open(ThreadID) ;
thread.Kill(KErrCancel) ;
thread.Close() ;


这样我们就不会在退出时出错了,我们还要注意的是,如果线程已经关闭,这时再调用thread.Close()就会报告Kern-exec 3错误,这表明这是对一个空白handler进行误操作了,这个一定要避免。

再 来看AO,AO可以完成众多复杂的任务,譬如说包纳线程,用自己的RunL()来响应线程完成后的操作,或是直接充当一个信号灯的作用。不管如何操作,我 们需要注意的一点是,在使用User::RequestComplete()时,我们一定要将iStatus设置为KRequestPending,这个 很重要,还有RequestComplete()的参数也要设置好,否则不能执行成功。

另外,在设置好一个请求后,要调用 SetActive()函数,以便通知Scheduler有等候的请求,当调用它后,我们就一定要完成这个请求,否则这个请求就会是一个stray请求事 件,会引发错误,如在下一次调用SetActive()时就会产生E32User-CBase 42错误,我们采用IsActive()的判断也很重要, 可以避免这方面的错误:)

总之,AO的使用要谨慎大胆,从它派生个对象出来,不要忘了RunL(), DoCancel(),以及构造函数中CActive的优先级的设置哦:)

最后还有一个地方要注意,就是在线程内如何通知另一个线程的AO的请求完成那,如果是通知主线程的话,那我们要获得主线程的ID,这可以通过调用RThread::Id()来获得,如:
RThread trd;
iThreadParam.iThreadId = trd.Id();
trd.Close();

这样我们在另一个线程中便可以使用RThread::RequestComplete()来通知主线程的AO了,呵呵,如果是其他线程那可以通过线程的名字
阅读(809) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~