Common problems with active objects, and how to avoid them.
Set the relative
priorities of your active objects appropriately. The initial priority
is passed to the base class constructor in the active object's member
initialization list. You can change the priority by calling CActive::SetPriority()
.
An active object's RunL()
should complete as quickly as possible so that other
events can be handled without delay. A higher priority active object
whose request has completed will not preempt the currently executing RunL()
of a lower priority active object in the same thread.
Add your active
object to the active scheduler. You do this by calling CActiveScheduler::Add()
at the end of the active object's second phase constructor (ConstructL()
).
Call SetActive()
immediately after making an asynchronous request.
Failing to do this will break the active scheduler's event-processing
loop resulting in a panic (E32USER-CBASE 46
).
A single active
object must not issue a second asynchronous request when one is already
outstanding. You can use CActive::IsActive()
to find
out if a request has already been issued. Some active objects always
call CActive::Cancel()
before making a new asynchronous
request. This checks if a request is in progress, and if so calls
the pure virtual CActive::DoCancel()
. You override
this function to call the request cancellation function of the asynchronous
service provider.
An active object
must not be deleted with a request still in progress. Call CActive::Cancel()
in your active object's destructor, and
cancel the asynchronous service provider's cancellation function in
your override of DoCancel()
.
User::WaitForRequest()
and the active object framework do not mix. User::WaitForRequest()
is most commonly used in test code to wait on an asynchronous request
by blocking the thread. The active scheduler's event loop already
contains a call to User::WaitForAnyRequest()
.
Do not allow
a leave generated by your active object to panic the thread. You can
either trap any leaves yourself inside RunL()
and
use a signal to propagate the error, or you can override CActive::RunError()
to handle a leave arising from your RunL()
method,
and return KErrNone
to indicate that the leave has
been handled. In a Qt application it is not possible to derive your
own active scheduler and override CActiveSheduler::Error()
.
In a Qt application
do not call CActiveSheduler::Start()
or CActiveSheduler::Stop()
. The application framework is responsible for creating, installing,
and stopping the active scheduler.
Copyright note. Some of the material in this topic is based with permission on a Symbian Foundation wiki article Active Objects which is part of the series The Fundamentals of Symbian C++. The version used was that available at http://developer.symbian.org/ on 3 November 2010. The content in this page is licensed under the Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License (http://creativecommons.org/licenses/by-sa/2.0/uk).