×
Namespaces

Variants
Actions

多线程与AO(活动对象)

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

文章
huwell 在 29 Jun 2007 创建
最后由 hamishwillee 在 15 Dec 2011 编辑

在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了,呵呵,如果是其他线程那可以通过线程的名字:)


总的来说,对线程和AO的使用要细心:)

This page was last modified on 15 December 2011, at 13:04.
62 page views in the last 30 days.
×