Funktionsweise der asynchronen Bindung und Speicherung
Asynchroner Speicher verbessert die Spezifikation für strukturierten COM-Speicher, um das Herunterladen von Speicherobjekten in Netzwerken mit hoher Latenz und langsamen Verbindungen wie dem Internet zu unterstützen. Asynchroner Speicher arbeitet mit asynchronen Monikern zusammen, um ein vollständiges asynchrones Bindungsverhalten bereitzustellen.
In eine Webseite eingebettetes Dokumentobjekt
Wenn ein Benutzer auf einen Link klickt, der ein in eine Webseite eingebettetes Dokument darstellt, treten die folgenden Ereignisse auf:
Der Browser ruft die MkParseDisplayName-Funktion auf und übergibt die Link-URL.
MkParseDisplayName analysiert die URL, erstellt einen entsprechenden asynchronen Moniker und gibt einen Zeiger auf die IMoniker-Schnittstelle des Monikers zurück.
Der Browser ruft IsAsyncMoniker auf, um zu bestimmen, ob der Moniker asynchron ist, erstellt einen Bindungskontext, registriert die IBindStatusCallback-Schnittstelle beim Bindungskontext, nur wenn der Moniker asynchron ist, und ruft IMoniker::BindToObject auf, wobei der Bindungskontext übergeben wird.
Der Moniker bindet an das Objekt und fragt es für die IPersistMoniker-Schnittstelle ab, die angibt, ob das Objekt asynchrone Bindung und Speicherung unterstützt. Wenn das Objekt einen Zeiger auf IPersistMoniker zurückgibt:
- Der URL-Moniker ruft IPersistMoniker::Load auf und übergibt seinen eigenen IMoniker-Zeiger auf das Objekt.
- Das Objekt ändert den Bindungskontext, wählt aus, ob es einen blockierenden oder nicht blockierenden Speicher möchte, registriert sein eigenes IBindStatusCallback und ruft IMoniker::BindToStorage auf dem Zeiger auf, den es über IPersistMoniker::Load empfangen hat.
- Der Moniker erstellt einen asynchronen Speicher, behält einen Verweis auf die IFillLockBytes-Schnittstelle des Wrapperobjekts bei, registriert die IProgressNotify-Schnittstelle im Stammspeicher und ruft IPersistStorage::Load auf und übergibt den IStorage-Zeiger des asynchronen Speichers. Wenn Daten (in einem Hintergrundthread) eingehen, ruft der Moniker IFillLockBytes auf, um die ILockBytes in der temporären Datei aufzufüllen .
- Das Objekt liest Daten aus dem Speicher und gibt aus IPersistMoniker::Load zurück, wenn es genügend Daten empfangen hat, um sich als initialisiert zu betrachten. Wenn das Objekt versucht, Daten zu lesen, die noch nicht heruntergeladen wurden, erhält der Downloader eine Benachrichtigung zu IProgressNotify. Innerhalb der IProgressNotify::OnProgress-Methode blockiert der herunterladende Thread entweder eine modale Nachrichtenschleife oder bewirkt, dass der asynchrone Speicher E_PENDING zurückgibt, je nachdem, ob das Objekt einen blockierenden oder nicht blockierenden Speicher angefordert hat.
Wenn das Objekt IPersistMoniker nicht implementiert, fragt der Moniker IPersistStorage ab, was angibt, dass der persistente Zustand des Objekts in einem Speicherobjekt gespeichert wird. Wenn das Objekt einen Zeiger auf IPersistStorage zurückgibt:
- Der Moniker ruft IMoniker::BindToStorage für sich selbst auf, fordert eine blockierende IStorage an (da das Objekt nicht asynchron unterstützt), erstellt einen asynchronen Speicher, behält einen Verweis auf die IFillLockBytes-Schnittstelle des Wrappers bei, registriert die IProgressNotify-Schnittstelle im Stammspeicher und ruft IPersistStorage::Load auf, wobei der IStorage-Zeiger des asynchronen Speichers übergeben wird. Wenn Daten (in einem Hintergrundthread) eingehen, ruft der Moniker IFillLockBytes auf, um die ILockBytes in der temporären Datei aufzufüllen.
- Das Objekt liest Daten aus dem Speicher und gibt aus IPersistStorage::Load zurück, wenn es genügend Daten empfangen hat, um sich als initialisiert zu betrachten. Wenn das Objekt versucht, Daten zu lesen, die noch nicht heruntergeladen wurden, erhält es eine Benachrichtigung zu IProgressNotify. Innerhalb der IProgressNotify::OnProgress-Methode blockiert der herunterladende Thread immer in einer modalen Nachrichtenschleife.
Unabhängig davon, ob der Download synchron oder asynchron ist, gibt der Moniker von IMoniker::BindToObject zurück, und der Browser empfängt das angeforderte initialisierte Objekt.
Der Browser fragt IOleObject ab und hostet das Objekt als Dokumentobjekt. (An diesem Punkt wird das Objekt möglicherweise nicht vollständig initialisiert, aber genug, um etwas Nützliches anzuzeigen, in diesem Fall wird der Download im Hintergrund fortgesetzt.)