Archived:Change a synchronous Symbian C++ method to act like an asynchronous one
| Line 1: | Line 1: | ||
__NOTOC__ | __NOTOC__ | ||
__NOEDITSECTION__ | __NOEDITSECTION__ | ||
| − | + | {{KBCS}} | |
{|style="background:#eceff2" width="660px" border="1" cellpadding="5" cellspacing="0" | {|style="background:#eceff2" width="660px" border="1" cellpadding="5" cellspacing="0" | ||
|- | |- | ||
| − | |'''ID''' || | + | |'''ID''' ||CS001010 |
| − | |'''Creation date''' || | + | |'''Creation date''' || June 10, 2008 |
|- | |- | ||
|'''Platform''' || S60 3rd Edition, MR | |'''Platform''' || S60 3rd Edition, MR | ||
| Line 22: | Line 22: | ||
==Overview== | ==Overview== | ||
| − | This code snippet shows how to | + | This code snippet shows how to modify a synchronous method to behave like an asynchronous method. |
| − | There | + | There are two different methods: |
| − | * void LongRunningTaskL(TInt& aResult) is synchronous method that | + | * <tt>void LongRunningTaskL(TInt& aResult)</tt> is a synchronous method that acts like an asynchronous one but returns when the task has been completed. |
| − | * void LongRunningTaskL(MMySynchronousTaskDone* aObserver) is synchronous method that | + | * <tt>void LongRunningTaskL(MMySynchronousTaskDone* aObserver)</tt> is a synchronous method that acts like an asynchronous method. Note that the method returns right after it has been started and notifies of task completion via <tt>MMySynchronousTaskDone</tt>. |
==MMP file== | ==MMP file== | ||
| Line 62: | Line 62: | ||
public: | public: | ||
| − | // Synchronous method that | + | // Synchronous method that acts like an asynchronous one |
| − | // but returns when task | + | // but returns when task completed. |
void LongRunningTaskL(TInt& aResult); | void LongRunningTaskL(TInt& aResult); | ||
| − | // Synchronous method that | + | // Synchronous method that acts like an asynchronous one |
| − | // note that method returns right after it has been started | + | // note that the method returns right after it has been started |
| − | // and notifies task completion via MMySynchronousTaskDone | + | // and notifies of task completion via MMySynchronousTaskDone |
void LongRunningTaskL(MMySynchronousTaskDone* aObserver); | void LongRunningTaskL(MMySynchronousTaskDone* aObserver); | ||
| Line 141: | Line 141: | ||
} | } | ||
| − | // This method returns right after synchronous task is started | + | // This method returns right after the synchronous task is started |
void CMySynchronousClass::LongRunningTaskL(MMySynchronousTaskDone* aObserver) | void CMySynchronousClass::LongRunningTaskL(MMySynchronousTaskDone* aObserver) | ||
{ | { | ||
| Line 263: | Line 263: | ||
==Postconditions== | ==Postconditions== | ||
| − | + | The synchronous method acts like an asynchronous one. | |
==See also== | ==See also== | ||
| − | [[ | + | [[CS000982 - Using CActiveSchedulerWait]] |
[[Change_asynchronous_method_into_synchronous]] | [[Change_asynchronous_method_into_synchronous]] | ||
| − | [[Category:Symbian C++]][[Category:Code Examples]] | + | [[Category:Symbian C++]][[Category:Code Examples]][[Category:S60 3rd Edition]] |
Revision as of 12:54, 10 June 2008
| ID | CS001010 | Creation date | June 10, 2008 |
| Platform | S60 3rd Edition, MR | Tested on devices | Nokia N95 |
| Category | Symbian C++ | Subcategory | Code Examples |
| Keywords (APIs, classes, methods, functions): CActiveSchedulerWait, CActive, TRequestStatus |
Overview
This code snippet shows how to modify a synchronous method to behave like an asynchronous method.
There are two different methods:
- void LongRunningTaskL(TInt& aResult) is a synchronous method that acts like an asynchronous one but returns when the task has been completed.
- void LongRunningTaskL(MMySynchronousTaskDone* aObserver) is a synchronous method that acts like an asynchronous method. Note that the method returns right after it has been started and notifies of task completion via MMySynchronousTaskDone.
MMP file
The following capabilities and libraries are required:
CAPABILITY None
LIBRARY euser.lib
Header
#include <e32base.h>
class MMySynchronousTaskDone
{
public:
virtual void TaskDone(TInt aRet) = 0;
};
class CMySynchronousClass : public CActive
{
enum EState
{
EIdle = 0,
EStarted,
ERunningTask1,
ERunningTask2,
ERunningTask3,
EEnd
};
public:
static CMySynchronousClass* NewL();
virtual ~CMySynchronousClass();
public:
// Synchronous method that acts like an asynchronous one
// but returns when task completed.
void LongRunningTaskL(TInt& aResult);
// Synchronous method that acts like an asynchronous one
// note that the method returns right after it has been started
// and notifies of task completion via MMySynchronousTaskDone
void LongRunningTaskL(MMySynchronousTaskDone* aObserver);
private: // From CActive
void RunL();
TInt RunError(TInt aError);
void DoCancel();
private:
CMySynchronousClass();
void ConstructL();
void GiveTimeToOthers();
void DoLongRunningTask();
private:
EState iRunningState;
CActiveSchedulerWait* iSchedulerWait;
TInt iSomeLongRunningTask;
MMySynchronousTaskDone* iObserver;
};
Source
CMySynchronousClass* CMySynchronousClass::NewL()
{
CMySynchronousClass* self = new (ELeave) CMySynchronousClass();
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
CMySynchronousClass::CMySynchronousClass():CActive(EPriorityStandard)
{
}
void CMySynchronousClass::ConstructL()
{
CActiveScheduler::Add(this);
iSchedulerWait = new (ELeave) CActiveSchedulerWait();
}
CMySynchronousClass::~CMySynchronousClass()
{
Cancel();
delete iSchedulerWait;
}
// This method returns after synchronous task completion
void CMySynchronousClass::LongRunningTaskL(TInt& aResult)
{
if (iRunningState == EIdle)
{
iSomeLongRunningTask = 0;
iRunningState = EStarted;
GiveTimeToOthers();
iSchedulerWait->Start();
// Continues here after CActiveSchedulerWait::AsyncComplete() is called
if (iStatus.Int() != KErrNone)
{
User::Leave(iStatus.Int());
}
aResult = iSomeLongRunningTask;
}
else
{
User::Leave(KErrNotReady);
}
}
// This method returns right after the synchronous task is started
void CMySynchronousClass::LongRunningTaskL(MMySynchronousTaskDone* aObserver)
{
if (iRunningState == EIdle)
{
iObserver = aObserver;
iSomeLongRunningTask = 0;
iRunningState = EStarted;
GiveTimeToOthers();
}
else
{
User::Leave(KErrNotReady);
}
}
void CMySynchronousClass::DoLongRunningTask()
{
// TODO: Here is a synchronous method call.
// Try to split call in small parts.
iSomeLongRunningTask++;
}
void CMySynchronousClass::GiveTimeToOthers()
{
TRequestStatus* status = &iStatus;
User::RequestComplete( status, KErrNone );
SetActive();
}
void CMySynchronousClass::RunL()
{
switch (iRunningState)
{
case EIdle:
{
break;
}
case EStarted:
{
iRunningState = ERunningTask1;
// TODO: Call synchronous method
DoLongRunningTask();
GiveTimeToOthers();
break;
}
case ERunningTask1:
{
iRunningState = ERunningTask2;
// TODO: Call synchronous method
DoLongRunningTask();
GiveTimeToOthers();
break;
}
case ERunningTask2:
{
iRunningState = ERunningTask3;
// TODO: Call synchronous method
DoLongRunningTask();
GiveTimeToOthers();
break;
}
case ERunningTask3:
{
iRunningState = EEnd;
// TODO: Do some end processing if needed
GiveTimeToOthers();
break;
}
case EEnd:
{
// Done
iRunningState = EIdle;
if (iObserver)
{
iObserver->TaskDone(iSomeLongRunningTask);
}
if (iSchedulerWait->IsStarted())
{
iSchedulerWait->AsyncStop();
}
break;
}
default:
{
if (iSchedulerWait->IsStarted())
{
iSchedulerWait->AsyncStop();
}
break;
}
};
}
TInt CMySynchronousClass::RunError(TInt aError)
{
if (iObserver)
{
iObserver->TaskDone(aError);
}
return KErrNone;
}
void CMySynchronousClass::DoCancel()
{
if (iObserver)
{
iObserver->TaskDone(KErrCancel);
}
if (iSchedulerWait->IsStarted())
{
iSchedulerWait->AsyncStop();
}
}
Postconditions
The synchronous method acts like an asynchronous one.

