How to stop the thread created in CImageDecoder?
| Mon, 2005-01-31 12:04 | |
|
Dear All,
In my app, I used the CImageDecoder to decode a bmp file with the EOptionAlwaysThread parameter to call the member function Convert() of CImageDecoder class. After finish the decoding, the app cannot be terminated exactly. The following is my code fragment: class CImageHandler : public CActive { public: static CImageHandler* NewL(RFs& fs); ~CImageHandler(); private: CImageHandler(RFs& fs); public: // It is the caller's responsobility to delete the return pointer CFbsBitmap* LoadFileL(const TDesC& aFilename); private: // Active object interface void RunL(); void DoCancel(); private: CImageDecoder* iLoadUtil; RFs& iFs; }; ////////////////////////// CImageHandler* CImageHandler::NewL(RFs& fs) { CImageHandler* p=new (ELeave) CImageHandler(fs); CActiveScheduler::Add(p); return p; } CImageHandler::CImageHandler(RFs& fs) : CActive(CActive::EPriorityStandard), iFs(fs) { } CImageHandler::~CImageHandler() { Cancel(); Deque(); delete iLoadUtil; } //the decoder function CFbsBitmap* CImageHandler::LoadFileL(const TDesC& aFilename) { ASSERT(!IsActive()); if(IsActive()) return NULL; delete iLoadUtil; iLoadUtil = NULL; iLoadUtil = CImageDecoder::FileNewL(iFs, aFilename, CImageDecoder::EOptionAlwaysThread); // Bitmap CFbsBitmap* pBitmap = new CFbsBitmap(); if(pBitmap) { //some line to create the CFbsBitmap ...... iLoadUtil->Convert(&iStatus, *pBitmap, 0); SetActive(); User::WaitForRequest(iStatus); if(iStatus.Int() != KErrNone) { delete pBitmap; pBitmap = NULL; } } return pBitmap; } void CImageHandler::RunL() { } void CImageHandler::DoCancel() { // Cancel everything possible if(iLoadUtil) iLoadUtil->Cancel(); } ///////////////////////////////////////////// I use the User::WaitForRequest(iStatus) function to wait the thread decode the file synchronously. The app can run in success, but cannot exit. I had done my best but I still failed to find the reason. Pleas help me. Thanks in advance. |
|






Forum posts: 1379
Try this
{
public:
static CImageHandler* NewL(RFs& fs);
~CImageHandler();
private:
CImageHandler(RFs& fs);
public:
CFbsBitmap* LoadFileL(const TDesC& aFilename);
private:
CImageDecoder* iLoadUtil;
RFs& iFs;
};
And
CImageHandler* CImageHandler::NewL(RFs& fs)
{
CImageHandler* p=new (ELeave) CImageHandler(fs);
return p;
}
CImageHandler::CImageHandler(RFs& fs) :
iFs(fs)
{
}
CImageHandler::~CImageHandler()
{
delete iLoadUtil;
}
//the decoder function
CFbsBitmap* CImageHandler::LoadFileL(const TDesC& aFilename)
{
delete iLoadUtil;
iLoadUtil = NULL;
iLoadUtil = CImageDecoder::FileNewL(iFs, aFilename,
CImageDecoder::EOptionAlwaysThread);
// Bitmap
CFbsBitmap* pBitmap = new CFbsBitmap();
if(pBitmap)
{
//some line to create the CFbsBitmap
TRequestStatus stat = KRequestPending;
iLoadUtil->Convert(&stat, *pBitmap, 0);
User::WaitForRequest(stat);
if(stat.Int() != KErrNone)
{
delete pBitmap;
pBitmap = NULL;
}
}
return pBitmap;
}
Or, make it really asyncronous and don't call waitforrequest - RunL will then be called when the conversion has been completed.
didster
Forum posts: 110
BTW you need to provide more info about what happens when you try to exit your app, otherwise we can't really help with that. One other thing, you don't need to call Deque() in the destructor. That is done for you by the base class.
Forum posts: 1379
The discussion on why this was added is here: http://www.symbian.com/developer/techlib/v70sdocs/doc_source/DevGuides/cpp/MultiMedia/ImageConverterLibrary/ICLGuide_AdvancedFeatures.html
didster
Forum posts: 110
The point is that if you do the decoding synchronously using your applications main thread you are guaranteed to freeze the application and that's a very bad idea, unless of course you deliberately want to annoy the hell out of the person who is using your app. You should always give the user the option of cancelling the operation and you simply can't do that if you are doing the decoding synchronously.
Forum posts: 8
Forum posts: 53
Now i solved my problem, too.
in synchronous Situation ( no CActive class):
use:
CImageDecoder::EOptionAlwaysThread instand CImageDecoder::EOptionNone
iBitmap = new (ELeave) CFbsBitmap();
iBitmap->Create(imageDecoder->FrameInfo().iOverallSizeInPixels, imageDecoder->FrameInfo().iFrameDisplayMode);//EColor4K);
TRequestStatus status;//iState = EDecoding;
imageDecoder->Convert( &status, *iBitmap );
User::WaitForRequest(status);