用Active Object分割长时间运行任务
文章信息
用Active Object分割长时间运行任务
CSimpleAO例子代码演示了一个能用AO(Active Object)分割长时间运行任务的框架。仅适用于能分割成多个步骤的任务,然后每个步骤在DoOneRound函数中进行处理。 在使用活动对象时的一些要点是构造活动对象时必须指定优先级、使用前总是被添加到CActiveScheduler(如ConstructL函数所示)、异步函数执行后必须调用SetActive函数。
注意:活动对象的优先级应当总是设得尽可能小些,这个很重要。因为如果优先级设置太高的话,长时间运行任务仍然能阻塞其它低优先级的事件处理。
扩展这个例子代码时,所有的初始化工作都应添加到StartProcess函数中,而每个处理步骤代码应添加到DoOneRound函数中。
SimpleAO.cpp
CSimpleAO* CSimpleAO::NewL(MSimpleAOObserver& aObserver)
{
CSimpleAO* self = NewLC(aObserver);
CleanupStack::Pop(self);
return self;
}
CSimpleAO* CSimpleAO::NewLC(MSimpleAOObserver& aObserver)
{
CSimpleAO* self = new (ELeave) CSimpleAO(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CSimpleAO::CSimpleAO(MSimpleAOObserver& aObserver)
:CActive(0),iObserver(aObserver)
{
}
CSimpleAO::~CSimpleAO()
{
Cancel();
}
void CSimpleAO::ConstructL(void)
{
CActiveScheduler::Add(this);
}
void CSimpleAO::StartProcess(void)
{
iRounds = 100;
iCurrent= 0;
iError = KErrNone;
iCancel= EFalse;
TRequestStatus* status=&iStatus;
User::RequestComplete(status, KErrNone);
SetActive();
}
void CSimpleAO::DoCancel()
{
iCancel = ETrue;
}
void CSimpleAO::RunL()
{
iError = iStatus.Int();
if(iError != KErrNone || (iCurrent > iRounds))
{
FinnishedL();
}
else
{
iObserver.MeProcessL(iCurrent,iRounds);
TInt Err = DoOneRound();
TRequestStatus* status=&iStatus;
User::RequestComplete(status, Err);
SetActive();
}
}
TInt CSimpleAO::DoOneRound(void)
{
TInt RetError(KErrNone);
// do one step on the process in here and update variables;
iCurrent++;
return RetError;
}
void CSimpleAO::FinnishedL(void)
{
iObserver.MeFinnishL(this,iError);
}
SimpleAO.h
#include <e32base.h>
#include <F32FILE.H>
class MSimpleAOObserver
{
public: // New methods
virtual void MeProcessL(TInt aNow,TInt aFull) = 0;
virtual void MeFinnishL(CSimpleAO* aObject, TInt aError) = 0;
};
class CSimpleAO : public CActive
{
public:
static CSimpleAO* NewL(MSimpleAOObserver& aObserver);
static CSimpleAO* NewLC(MSimpleAOObserver& aObserver);
~CSimpleAO();
void StartProcess(void);
protected:
void DoCancel();
void RunL();
private:
TInt DoOneRound(void);
void FinnishedL(void);
private:
MSimpleAOObserver& iObserver;
TBool iCancel;
TInt iCurrent,iRounds,iError;
};


(no comments yet)