Always live in the process of synchronization, is undoubtedly one of the biggest expectations of my code-work. In order not to block the UI, in order to read and write a piece of data, in order to get over the complexity of the logic of the calculation, in order to get along with the common work, always need asynchronous processing, you a little bit of me to complete the task In Symbian, there is a set of mechanisms to do this, which is active Objects.
Active Objects
Active object is a set of event-driven multitasking models. In Symbian's standard line thread (removing some Java construction threads, native c construction threads, and so on) contains a message loop, in the loop, The query registers the Trequeststatus state of each activeobject of the Cactivescheduler to which the thread belongs, and immediately activates and executes once the executable task is found. The classic Loop pseudo code is as follows:
// *** in the loop ***
User::WaitForAnyRequest();
FOREVER
{
if(activeObject->IsActive() && activeObject->iStatus != KRequestPending)
{
activeObject->iActive = EFalse;
TRAPD(r, activeObject->RunL());
if( r != KErrNone )
{
r = activeObject->RunError();
if( r != KErrNone )
Error(r);
}
break;
}
}
A code solution thousand words. In the message loop, wait for the event to activate, and then traverse the query to register the status of each active object. Of course, simple traversal is not decent, each active object is a priority, there is no doubt that high priority will be given priority to execute, the low will never exceed. By default, everyone uses Eprioritystandard, everything is peaceful. If an active object needs to be executed for a long time, consider using low-priority, Epriorityidle, Eprioritylow, which can perform less frequently. And if the task is to have some real-time requirements, you need to use high priority, also such as Epriorityuserinput, Epriorityhigh.
But this model is not enough to meet the real-time requirements, because it is not preemptive. A low priority task, is scheduled, where grinding Ji Ji, you are no higher priority. In this mode, to maintain a good response ability, need self-discipline. First, if a task is high in real time, it needs to be tuned to the priority of the thread or process, allowing it to be prioritized by the CPU, without the opportunity to execute the low-priority task. Also, don't put the inefficient code in the RUNL of active object (if it's not the main thread, watch the well with rice ...) , which causes the thread to lose the ability to respond to other requests.
Each asynchronous task needs to derive from the Cactive class. If you use the System Wizard, you can find that Symbian wants each cactive subclass to do the following things:
Implement RUNL, place the execution code that waits for the callback party;
Implement the Docancel method to properly place the task without the opportunity to arrive at the destination, which is a template method pattern that will be put on cancel and will be invoked only when the state is executed;
Implement Runerror, after the execution error, give the cactive a chance of self redemption;
Try telling the user that there is no free lunch in the world and that you need to send the request to the performer with setactive to help you fix the problem.
The core of the task-driven control is trequeststatus, where the execution party will set the Trequeststatus to be krequestpending when the task is received, and when this state is changed again, The Cactivescheduler dispatch execution callback is triggered. The whole process is shown in the following image (still stolen) ... ):