亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 676 | 回復: 0
打印 上一主題 下一主題

活動對象框架原理 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-12-21 08:41 |只看該作者 |倒序瀏覽
一、概述:

Symbian OS是一個多任務的操作系統(tǒng),那么為了實現(xiàn)多任務,同時使系統(tǒng)能夠快速響應,高效的進行事件處理,并減輕應用程序員的工作負擔(申請大多數(shù)耗時的操作(例如文件系統(tǒng))由服務提供器來完成,服務提供器完成程序員提交的請求后,將會返回給程序員一個成功或失敗的信號。),Symbian OS特意引入了活動對象的概念。

服務提供器API具有函數(shù)的異步和同步版本,供客戶應用程序使用。所謂同步是指,客戶提交請求后,處于等待狀態(tài),等待服務提供器返回成功或失敗的信號后,然后在進行其他操作;所謂異步是指,請求完成,即返回信號之前,調用者也許會繼續(xù)執(zhí)行其他的處理,或者只是簡單的等待。在這里的等待,也可以稱為阻塞,信號就是一個事件,我們的代碼就是事件驅動的。為了實現(xiàn)多任務,一般我們使用異步API。

一般操作系統(tǒng)為了實現(xiàn)多任務,往往使用多線程實現(xiàn),當然,Symbian也是支持多線程的。但是,在同一個線程中運行的活動對象之間進行切換的代價要比線程上下文的切換代價低,這使得對于各種資源比較緊張的Symbian OS來說,使得活動對象更適合事件驅動多任務。

注意:

1)線程間上下文切換和同一線程的活動對象之間傳遞控制權,在速度上的差別可能會有10倍之差,另外,一個線程大約在內核中有4KB的空間開銷,在用戶空間上有8KB的用于程序棧的空間開銷,而一個活動對象的開銷可能只有幾百字節(jié),甚至更小。

2)雖然在一個線程內的活動對象是非搶占式地協(xié)同運行的,但在它們所在的線程卻是搶占式調度的。

 

二、概念:

一個活動對象必須派生自基類CActive

class CActive : public CBase

{

public:

    enum Tpriority

    {

        EPriorityIdle = -100;

        EPriorityLow = -20;

        EPriorityStandard = 0;

        EPriorityUserInput = 10;

        EPriorityHigh = 20;

    }

public:

    IMPORT_C ~CActive ();

    IMPORT_C void Cancel ();//刪除未完成請求的函數(shù)

……

    IMPORT_C void SetPriority (TInt aPriority);

    Inline TBool IsActive () const;

……

protected:

    IMPORT_C CActive (TInt aPriority);

    IMPORT_C void SetActive ();

    virtual void DoCancel () = 0;//兩個純虛函數(shù),繼承類必須實現(xiàn)它們

    virtual void RunL () = 0;//處理函數(shù)

    IMPORT_C virtual TInt RunError (TInt aError);

public:

    TrequestStatus iStatus;//代表請求狀態(tài)

……

private:

    TBool iActive;

……

}

通過上面的CActive聲明可以看出:活動對象和線程類似,構造時也會有一個優(yōu)先級值來決定它們如何被調度,通常為活動對象提供一個標準優(yōu)先級EPriorityStandard。當活動對象響應的異步服務完成時,就會產生一個事件;顒诱{度器會偵測到事件,并決定每個事件對應的是哪個活動對象,然后調用恰當?shù)幕顒訉ο笕ヌ幚硎录?/span>當活動對象處理事件時,直到事件處理函數(shù)返回到活動調度器,該對象都是無法被搶占的,也就是說,RunL()事件處理函數(shù)是一個原子操作。

Symbian OS中,活動對象相互協(xié)作并順序的實現(xiàn)多任務,也不需要對共享的資源進行同步保護。另外,因為活動對象在同一個線程中運行,所以可以更容易地共享內存和對象,盡管活動對象存在于同一線程,但它們仍然是各自獨立運行的,這就好像同一個進程中的線程是獨立運行的一樣。

 

三、關于活動對象基類CActive的幾點說明:

參照上面CActive的聲明

1、必須在發(fā)布異步請求后調用SetActive(),否則活動對象規(guī)劃器在搜索已完成的活動對象時忽略它,從而導致錯誤。需要說明的是,CActive這個基類中,并沒有任何實際的函數(shù)用來發(fā)布異步請求,我們自己必須編寫這種函數(shù),通常取名為StartL()。

2DoCancel()是個純虛函數(shù),必須實現(xiàn)該函數(shù)以提供未完成請求所需的功能。但是,需要注意:絕對不應該直接調用該函數(shù),應該總是使用Cancel(),該函數(shù)調用DoCancel(),同時確保設置必須的標志,從而表明請求已完成。

3RunL()是原子操作,當它被活動規(guī)劃器調度后,相同線程里,其他任何RunL()都不可以運行,直到這一RunL()完成并返回,因此該方法必須簡短,否則,用戶就會感到等待事件較長,手機好像死機了一樣。

4如果RunL()異常退出,則調用RunError()(由活動規(guī)劃器調用),它為活動對象提供處理自身錯誤的機會。如果能夠處理錯誤,RunError()就應該返回KErrNone;否則,它應該只是返回作為參數(shù)傳遞的錯誤碼,在這種情況下,將錯誤傳遞到活動規(guī)劃器的Error()函數(shù),默認行為是導致嚴重錯誤。

5、iStatus實際上只是一個封裝的整數(shù),用于表示異步服務提供器返回的狀態(tài)或錯誤碼;顒訉ο蟀l(fā)出請求后,服務提供器的第一個任務是將iStatus設為KrequestPending,當請求的服務完成時,服務提供器將iStatus的值設為KErrNone(如果請求成功完成)或錯誤碼。

 

四、活動對象的實現(xiàn)步驟: 1、構造

活動對象幾乎總是要使用二階段構造,因為活動對象通常需要連接到它們的異步服務提供器,這個連接過程可能失敗。

void CCsvFileLoader::ConstructL (const TDesC& aFileName)

{

    iFileName = aFileName;

    //RFile iFile

    User::LeaveIfError(iFile.open(iFs , iFileName , EFileRead));

    //RTimer iTimeWaster

    User::LeaveIfError(iTimeWaster.CreateLocal());

    CActiveScheduler::Add(this);

    //活動對象加到活動規(guī)劃器中,這條語句也可以放在第一階段構造函數(shù)中

}

選擇最適合活動對象的優(yōu)先級,該優(yōu)先級只會影響活動對象在活動規(guī)劃器的列表中的順序,實際開發(fā)時,很少使用EPriorityStandard以外的優(yōu)先級。

CCsvFileLoader::CCsvFileLoader(RFs& aFs , CElementList& aElementList , MCsvFileLoaderObserver& aObserver) : CActive (EPriorityStandard)

{

    ……

}

通過句柄RTimerRFile鏈接到所需的兩個異步服務器。

警告:必須將活動對象都添加到活動規(guī)劃器中,并且只能添加一次。添加失敗將產生請求迷失的嚴重錯誤。

 

2、啟動活動對象

void CCsvFileLoader::Start( )

{

    TInt delay = (iFileName.Size() % 10) * 100000;

    iTimeWaster.After(iStatus , delay);

    SetActive();//iActive設為Etrue

}

異步服務提供器(運行在另一線程或進程中)將通過完成下面兩件事來用信號通知線程(活動對象所屬的線程)。

1)增加線程的信號量(這個信號量,一般情況用不到。只是當活動對象所屬的線程被掛起時,通過增加信號量重新喚醒這個線程,而線程的掛起通過函數(shù)WaitForAnyRequest())。

2)將給定的TRequestStatus設置為不同于KRequestPending的值(如果一切運行良好,則很有可能是KErrNone)。

3、RunL()

這個函數(shù)比較復雜,它將執(zhí)行大量任務:

1)決定下一次迭代應該做什么(加載數(shù)據(jù)或浪費時間)

2)檢查最后一次迭代狀態(tài),并且將這個狀態(tài)報告給觀察器

3)處理所有加載的數(shù)據(jù)

一般活動對象的這個RunL()方法希望完成上述的一項或幾項工作。

在這里還可以再次調用Start(),也就是說可以再次發(fā)布異步服務請求。

4、在RunError()中處理錯誤

活動對象完全允許RunL()異常退出,結尾是“L”表明了這一點。如果該函數(shù)確實異常退出,則它異常退出時的錯誤碼將被傳遞到RunError()。

TInt CCsvFileLoader::RunError(TInt aError)

{

    iObserver.NotifyLoadCompleted(aError , *this);

    return KErrNone;

}

這里的錯誤處理很簡單,僅僅將錯誤傳遞給了觀察器。

5、刪除未完成的請求

所有的活動對象都必須實現(xiàn)一個DoCancel()方法,用于刪除任何未完成的請求。

void CCsvFileLoader::DoCancel()

{

    if(iWastingTime || !iHaveTriedToLoad)

    {

        iTimeWaster.Cancel();

    }

}

CActive::Cancel調用DoCancel(),絕對不允許重寫CActive::Cancel()自身(它無論如何都不是虛函數(shù)),因為該函數(shù)完成了大量重要的工作。

1)檢查活動對象是否實際上處于活動狀態(tài)。如果不是,它就會返回,而不作任何事情。

2)調用DoCancel()

3)等待請求完成,這必須盡可能完成(原始請求可能在刪除它之前就已經(jīng)完成)

4iActive設為假

注意:可以重寫DoCancel()方法,但不可以重寫Cancel()方法,這個方法會自動調用DoCancel(),另外,我們也不能直接調用DoCancel()方法,這一點也是很重要的。

6、析構函數(shù)

CCsvFileLoader::~CCsvFileLoader()

{

    Cancel();

    iFile.close();

    iTimeWaster.Close();

}

任何活動對象析構函數(shù)的第一步都是調用Cancel()刪除任何未完成的請求。如果刪除一個帶有未完成請求的活動對象,則產生一個請求迷失的嚴重錯誤。

必須關閉異步服務提供器的任何句柄,從而避免資源泄漏。

CActive析構函數(shù)將自動調用Deque(),從活動規(guī)劃器列表中移除活動對象。

7、啟動活動規(guī)劃器

UI框架將自動創(chuàng)建、安裝和啟動活動規(guī)劃器。因此,如果不打算編寫.exe(控制臺應用程序或Symbian OS服務器)或DLL(需要顯式啟動活動規(guī)劃器),則可以省略這些步驟。

啟動活動規(guī)劃器前,必須完成如下步驟:

1)實例化活動規(guī)劃器

2)將其安裝到線程中

3)創(chuàng)建一個活動對象并添加到活動規(guī)劃器中

4)發(fā)出一個請求

void DoExampleL()

{

    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;

    CleanupStack::PushL(scheduler);

    CActiveScheduler::Install(scheduler);

    CElementsEngine* elementEngine = CElementsEngine::NewLC(*console);

    elementEngine->LoadFromCsvFilesL();//發(fā)出請求

    CActiveScheduler::Start();//啟動活動規(guī)劃器

    CleanupStack::PopAndDestroy(2 , scheduler);

}

 

五、常見的活動對象錯誤:

1、啟動活動對象前忘記調用CActiveScheduler::Add()

2、在發(fā)布或重新發(fā)布異步請求后沒有調用SetActive()

3、將相同的iStatus同時傳遞給兩個服務提供器(因此在相同的活動對象上有多個未完成的請求)
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP