在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了,呵呵,如果是其他线程那可以通过线程的名字
阅读(850) | 评论(0) | 转发(0) |