非同期バインディングとStorageのしくみ
非同期ストレージは、COM 構造化ストレージ仕様を強化し、インターネットなどの待機時間の長い低速リンク ネットワークでのストレージ オブジェクトのダウンロードをサポートします。 非同期ストレージは非同期モニカーと連携して、完全な非同期バインディング動作を提供します。
Web ページに埋め込まれたドキュメント オブジェクト
ユーザーが Web ページに埋め込まれたドキュメントを表すリンクをクリックすると、次のイベントが発生します。
ブラウザーは MkParseDisplayName 関数を呼び出し、リンク URL を渡します。
MkParseDisplayName は URL を解析し、対応する非同期モニカーを作成し、モニカーの IMoniker インターフェイスへのポインターを返します。
ブラウザーは IsAsyncMoniker を 呼び出してモニカーが非同期かどうかを判断し、バインド コンテキストを作成し、モニカーが非同期の場合にのみ IBindStatusCallback インターフェイスをバインド コンテキストに登録し、バインド コンテキストを渡して IMoniker::BindToObject を呼び出します。
モニカーはオブジェクトにバインドし、 IPersistMoniker インターフェイスに対してクエリを実行します。このインターフェイスは、オブジェクトが非同期バインディングとストレージをサポートしているかどうかを示します。 オブジェクトが IPersistMoniker へのポインターを返す場合:
- URL モニカーは IPersistMoniker::Load を呼び出し、独自の IMoniker ポインターをオブジェクトに渡します。
- オブジェクトはバインド コンテキストを変更し、ブロックストレージと非ブロッキング ストレージのどちらを使用するかを選択し、独自の IBindStatusCallback を登録し、IPersistMoniker::Load を介して受信したポインターに IMoniker::BindToStorage を呼び出します。
- モニカーは非同期ストレージを作成し、ラッパー オブジェクトの IFillLockBytes インターフェイスへの参照を保持し、ルート ストレージに IProgressNotify インターフェイスを登録し、 IPersistStorage::Load を呼び出し、非同期ストレージの IStorage ポインターを 渡します。 (バックグラウンド スレッドで) データが到着すると、モニカー は IFillLockBytes を呼び出して一時ファイルの ILockBytes を埋めます。
- オブジェクトはストレージからデータを読み取り、 IPersistMoniker::Load から返されます。初期化を考慮するのに十分なデータを受信した場合。 オブジェクトがまだダウンロードされていないデータの読み取りを試みると、ダウンローダーは IProgressNotify で通知を受け取ります。 IProgressNotify::OnProgress メソッド内では、ダウンロード スレッドはモーダル メッセージ ループ内でブロックするか、オブジェクトがブロックまたは非ブロックストレージを要求したかどうかに応じて、非同期ストレージがE_PENDINGを返します。
オブジェクトが IPersistMoniker を実装していない場合、モニカーは IPersistStorage を照会します。これは、オブジェクトの永続的な状態がストレージ オブジェクトに格納されていることを示します。 オブジェクトが IPersistStorage へのポインターを返す場合:
- モニカーは IMoniker::BindToStorage をそれ自体で呼び出し、ブロックしている IStorage (オブジェクトが非同期対応ではないため) を要求して非同期ストレージを作成し、ラッパー オブジェクトの IFillLockBytes インターフェイスへの参照を保持し、ルート ストレージに IProgressNotify インターフェイスを登録し、 IPersistStorage::Load を呼び出し、非同期ストレージの IStorage ポインターを 渡します。 データが (バックグラウンド スレッドで) 到着すると、モニカー は IFillLockBytes を呼び出して、一時ファイルの ILockBytes を埋めます。
- オブジェクトはストレージからデータを読み取り、 IPersistStorage::Load から返されます。初期化を考慮するのに十分なデータを受け取ったとき。 まだダウンロードされていないデータの読み取りを試みるオブジェクトは、 IProgressNotify で通知を受け取ります。 IProgressNotify::OnProgress メソッド内では、ダウンロード スレッドは常にモーダル メッセージ ループでブロックします。
ダウンロードが同期か非同期かに関係なく、モニカーは IMoniker::BindToObject から返され、ブラウザーは要求した初期化されたオブジェクトを受け取ります。
ブラウザーは IOleObject に対してクエリを実行し、オブジェクトをドキュメント オブジェクトとしてホストします。 (この時点では、オブジェクトは完全に初期化されていない可能性がありますが、便利なものを表示するのに十分です。その場合、ダウンロードはバックグラウンドで続行されます)。