掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.30233

非同期でのコールバック再帰処理の簡略化
投稿者---DD.(2007/05/30 00:01:41)


お世話になります。DD.と申します。

現在実装している処理をもう少し分かりやすい形にできないものかと試行錯誤しており、みなさんからのアドバイスと頂きたく投稿致します。

実装している処理に関してなのですが、
データリストから1件づつデータを読み取るという処理なのですが、
1件データを読み取る処理が非同期になっており、
読み取り完了後にコールバック関数が呼ばれるようになっています。
さらに、データリストから全件データ読み取り後に、
データ読み取り完了用の関数を呼び出すようになっています。
(これもコールバックです)

もしこれが同期であれば、
for ( int i = 0; i < リスト件数; ++i ) {
  データ読み取り関数();
}
読み込み完了コールバック();

だけなのですが、
非同期であるために、
hoge(){
  1件読み取り関数( cnt );
}

1件読み取り関数() {
  読み取り処理;
  ...
  コールバック関数A(read_data, cnt);
}

コールバック関数A( read_data, cnt ) {
  if ( cnt >= リスト件数 ) { 読み込み完了コールバック(); }
  ++cnt;
  1件読み取り関数( cnt ); // 次のデータ読み込み(またコールバック関数Aが呼び出される)
}

のような実装を行っております。

上記処理の何が不満かというところなのですが、
‘匹濆みが完了したかどうかを判定するために
 コールバック関数に現在何件目のデータを読み込んでいるかのカウント情 報を渡していること。

▲魁璽襯丱奪関数A()内で全件分の読み込みが完了したかどうかを判定し、
 読み込み完了コールバック()を呼び出しているため、
 コールバック関数A()には関係のないデータである、
 読み込み完了コールバック関数のポインタやそれに渡すデータなども
 コールバック関数A()に渡してやらなければいけないこと。

実際の処理は他の処理が入り込むため、全件読み込み完了条件時に
 コールバック関数内からコールバック関数を呼び出すなどの処理が、
 分かりにくくなりそうなこと。

以上の点が不満なところです。

尚、データ読み込み処理が1件づつであり、非同期であることは変更することができません。

極力各コールバックに引き渡すデータは最低限でありたいことと、
読み込み完了コールバック関数を呼び出す位置をなんとかしたいなどと思っています。

もっと分かりやすく実装できる案をご教授頂きたいと思います。

これだけでは分かりにくいということであればご指摘下さい。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:非同期でのコールバック再帰処理の簡略化 30237 金魚ちゃん 2007/05/30 14:34:57


No.30237

Re:非同期でのコールバック再帰処理の簡略化
投稿者---金魚ちゃん(2007/05/30 14:34:57)


良くわからないけど下の方法でどう。
------------------------------
int cnt; ←グローバル変数など

hoge(){
 cnt = 0; ←位置の初期化
 1件読み取り関数();
}

1件読み取り関数(){
 while ( cnt < リスト件数 ){
  読み取り処理;
  ...
  コールバック関数A( read_data );
 }
 読み込み完了コールバック();
}

コールバック関数A( read_data ){
 cnt++;
}
------------------------------
ちなみに、なぜコールバックを使うのですか?
全体像を知りたいです。



この投稿にコメントする

削除パスワード

No.30238

非同期でのコールバック再帰処理の簡略化
投稿者---DD.(2007/05/30 18:16:33)


回答ありがとうございます。

>int cnt; ←グローバル変数など
すいませんが、グローバル変数の使用は控えたいです。

>1件読み取り関数(){
> while ( cnt < リスト件数 ){
>  読み取り処理;
>  ...
>  コールバック関数A( read_data );
> }
> 読み込み完了コールバック();
>}
申し訳ありません。1点補足が抜けていました。
それに関して、
>ちなみに、なぜコールバックを使うのですか?
こちらと一緒に回答させて頂きます。

コールバック処理を呼び出している1件読み取り関数()は
提供されているライブラリが実装している部分であり、
こちらでは編集不可となります。。。

ですので、1件読み取り関数()をCallした後、
その読み取った内容をコールバック関数A()で受け取り処理するという形となります。

重要な補足部分が抜けてしまっており、申し訳ありません。

>全体像を知りたいです。
これに関しては、上記の「1件読み取り関数()は
提供されているライブラリが実装している部分」
という補足がなかったため、とても紛らわしくなっていたかと思います。

行いたい処理は、
○データリストからデータを全件分抽出するという処理であること。

ポイントは、
○データの抽出は外部提供のライブラリであること。
○データの抽出は1件づつでしかできないこと。
○データの1件抽出処理は"非同期"であり、データ抽出後に抽出したデータを渡したコールバック関数が呼ばれること。
○上記ロジックは変更不可であること。
○他のライブラリを使用することはできないこと。

となります。


この投稿にコメントする

削除パスワード

No.30248

Re:非同期でのコールバック再帰処理の簡略化
投稿者---金魚ちゃん(2007/05/31 10:52:05)


【1件読み取り関数】には1つ引数を渡せるんですよね。
そして【コールバック関数A】は自作できるんですよね。
それなら flag 変数のアドレスをポインタで【1件読み取り関数】に渡す。
その後、【コールバック関数A】で flag を OFF して hoge() 関数で監視。
------------------------------
hoge(){
 int cnt;
 
 for ( cnt = 0 ; cnt < リスト件数 ; cnt++ ){
  volatile int flag = 1;
  
  1件読み取り関数( &flag );
  
  while ( flag ){
   Sleep( 1 ); ←1ms(適当に決めて)
  }
 }
 読み込み完了コールバック();
}

1件読み取り関数(){
 読み取り処理;
 ...
 コールバック関数A( read_data, flag );
}

コールバック関数A( read_data, int *flag ){
 *flag = 0;
}
------------------------------
でどうでしょうか。

>他のライブラリを使用することはできないこと
なら Sleep も使えないのかな?



この投稿にコメントする

削除パスワード

No.30253

非同期でのコールバック再帰処理の簡略化
投稿者---DD.(2007/05/31 13:07:23)


再度の回答ありがとうございます。

も、申し訳ありません。。。

さらに忘れていましたorz

非同期動作であるため、
フラグなどで制御して、コールバックが返ってくるまで
WAITしておくという考え方においては
禁止となっておりまして・・・

ですので、
while( flg ) { sleep(100); }
のようにループで待つというのはできないのです。

最初はこのやり方でいく予定だったのですが、
ダメな方向となりまして^^;

それが、sleep()を入れてこちらでタスクをがめないようにしていてもです。。。

またまた、情報を展開しきれておらず申し訳ありません。
#あとは展開漏れは・・・ないはずです。。。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧