Long-running services and background objects

This document describes the use of background objects to respond to requests for long-running services.

System responsiveness is important. Threads must be responsive to their users — a delay of more than a few hundred milliseconds is generally unacceptable.

This implies that all RunL() functions should complete in a few hundred milliseconds in order to maintain system responsiveness.

In some cases, servicing a request may take longer than this. For example, printing a document, or sending a file, may take seconds or minutes to execute, but they should not hold up the main thread. It should also be possible to cancel long running services.

The preferred solution is to use a background active object running in the same thread as all other active objects

With this approach, the long running service is split into multiple chunks. The RunL() function allows itself to run for a relatively short period and then renews its request. This background active object tracks its own progress through the long running task so that when RunL() is next called, the it can continue from where it finished last time.

The background active object has a lower priority than other active objects in the thread. The user driven event-handling active objects can cancel the background active object by calling its Cancel() function.

The advantages of this approach are:

  • active objects are very cheap to create and use very few resources.

  • co-operating active objects cannot pre-empt each other; therefore, there is no need for locking and synchronization primitives when programming with multiple active objects.

  • active objects can share resources that are owned by a thread.

The active object framework allows the active-object implementation of a long-running operation to be concealed from the API, so that the service is presented to the user simply as an asynchronous request function together with an associated cancel function.

In cases where an active object implementation is impossible or impractical to program, then a background thread may be used to implement a long-running service. This approach is not recommended for code specifically designed for Symbian platform.