2006年02月15日

非同期の処理

アクティブオブジェクトによる非同期イベントの待機

 次に、メニューの[タイマーのスタート]を選択することにより、アクティブオブジェクトが非同期(ここでは1秒おき)にイベントを受け取ります。そのため、非同期イベントの発生源となるタイマを設定しますが、これはCActiveTest::After()関数で行われます。

void CActiveTest::After(){
iIsRunning = ETrue;
iTimer.After(iStatus, 1000000); // タイマのスタート
SetActive();
//このアクティブオブジェクトがスケジューリングの対象であることを示す
}

 ここで注目していただきたい点として、2点挙げます。

 まず1点目は、iTimer.After関数の第一引数に渡されるiStatusメンバです。このiStatusメンバはCActiveクラスで定義されているもので、非同期のイベントの完了を表すフラグです。iTimer.After関数は第二引数で指定した時間が経過すると、このiStatusの値をKErrNone(つまりKrequestPending以外の値)に設定します。先に述べたアクティブスケジューラの挙動とあわせて確認してください。

 2点目としては、この関数の一番最後に呼び出されているSetActive()関数です。この関数も、アクティブスケジューラに対して自身が非同期のイベントの通知を待っていることを表すために用います。

非同期イベントの通知

 タイマで設定した時間が過ぎ、エラーが発生していなければ、先に登録したアクティブオブジェクトのRunLの関数が呼び出されます。今回は(大まかですが)1秒置きにこのRunL関数が呼び出されますので、このRunL関数でラベルの書き換えを行っています。

void CActiveTest::RunL()
{
After();
sec ++ ;
if( sec >= 60 ){
sec = 0 ;
min ++ ;
}
if( min >= 60 ){
min = 0 ;
hour ++ ;
}
TBuf<32> text;
_LIT(KTime, "Time %d[h]%d[m]%d[s]");
text.Format(KTime, hour, min, sec );
label->SetTextL(text);
iContainer->DrawNow();
}

 ここで、CactiveTest::After()関数を呼び出しているのは、繰り返し1秒後にタイマから通知を受ける必要があるからです。

非同期のイベント待機のキャンセル

 イベント待機のキャンセルが行われた時の処理は、DoCancel関数に記述します。ここでは、RTimerクラスを用いて1秒置きのイベントを受け取っていますので、このリソースクラスに対してタイマのキャンセルをする必要があります。

void CActiveTest::DoCancel()
{
iTimer.Cancel();
iIsRunning = EFalse;
sec = min = hour = 0 ;
label->SetTextL(_L("タイマ停止"));
}

 また、CActiveクラスのデストラクタの中ではCansel関数を呼び出していますが、この関数はそのままDoCancel関数を呼び出します。

CActiveTest::~CActiveTest()
{
Cancel();
iTimer.Close();
}

最後に

 今回は、アクティブスケジューラとアクティブオブジェクトの二つを見ていきました。特にアクティブオブジェクトはコーディング量も若干多くなると思います。今回は処理ロジックをそのままRunL関数に書き込みましたが、再利用を考えると、何らかのコールバックを登録、RunLで登録したコールバックを呼び出せば汎用性が上がると思います。次回はファイル入出力について見ていく予定です。
posted by シンビアン at 13:55| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。