Поделиться через


Принцип работы асинхронной привязки и хранилища

Асинхронное хранилище расширяет спецификацию структурированного хранилища COM для поддержки скачивания объектов хранилища в сетях с высокой задержкой и медленной компоновкой, таких как Интернет. Асинхронное хранилище работает вместе с асинхронными моникерами, обеспечивая полное асинхронное поведение привязки.

Объект Document, внедренный на веб-страницу

Когда пользователь щелкает ссылку, представляющую документ, внедренный на веб-страницу, происходят следующие события:

  1. Браузер вызывает функцию MkParseDisplayName , передав URL-адрес ссылки.

  2. MkParseDisplayName анализирует URL-адрес, создает соответствующий асинхронный моникер и возвращает указатель на интерфейс IMoniker моникера.

  3. Браузер вызывает IsAsyncMoniker , чтобы определить, является ли моникер асинхронным, создает контекст привязки, регистрирует интерфейс IBindStatusCallback с контекстом привязки, только если моникер является асинхронным, и вызывает IMoniker::BindToObject, передав контекст привязки.

  4. Моникер привязывается к объекту и запрашивает у него интерфейс IPersistMoniker , который указывает, поддерживает ли объект асинхронную привязку и хранение. Если объект возвращает указатель на IPersistMoniker:

    1. Моникер URL вызывает IPersistMoniker::Load, передавая собственный указатель IMoniker на объект .
    2. Объект изменяет контекст привязки, выбирает, требуется ли ему блокировать или неблокировать хранилище, регистрирует собственный IBindStatusCallback и вызывает IMoniker::BindToStorage для указателя , полученного через IPersistMoniker::Load.
    3. Моникер создает асинхронное хранилище, сохраняет ссылку на интерфейс IFillLockBytes объекта-оболочки, регистрирует интерфейс IProgressNotify в корневом хранилище и вызывает IPersistStorage::Load, передавая указатель IStorage асинхронного хранилища. По мере поступления данных (в фоновом потоке) моникер вызывает IFillLockBytes для заполнения ILockBytes во временном файле.
    4. Объект считывает данные из хранилища и возвращает данные из IPersistMoniker::Load , когда получил достаточно данных, чтобы считать себя инициализированным. Если объект пытается считывать еще не скачанные данные, загрузчик получает уведомление в IProgressNotify. Внутри метода IProgressNotify::OnProgress поток загрузки либо блокирует модальный цикл сообщений, либо вызывает асинхронное хранилище для возврата E_PENDING в зависимости от того, запрашивал ли объект блокирующее или неблокирующее хранилище.
  5. Если объект не реализует IPersistMoniker, моникер запрашивает IPersistStorage, который указывает, что постоянное состояние объекта хранится в объекте хранилища. Если объект возвращает указатель на IPersistStorage:

    1. Моникер вызывает IMoniker::BindToStorage сам по себе, запрашивая блокирующий IStorage (поскольку объект не поддерживает асинхронный режим), создает асинхронное хранилище, сохраняет ссылку на интерфейс IFillLockBytes объекта-оболочки, регистрирует интерфейс IProgressNotify в корневом хранилище и вызывает IPersistStorage::Load, передав указатель IStorage асинхронного хранилища. По мере поступления данных (в фоновом потоке) моникер вызывает IFillLockBytes для заполнения ILockBytes во временном файле.
    2. Объект считывает данные из хранилища и возвращает данные из IPersistStorage::Load , если он получил достаточно данных, чтобы считать себя инициализированным. Если объект пытается прочитать данные, которые еще не были скачаны, он получает уведомление в IProgressNotify. Внутри метода IProgressNotify::OnProgress поток скачивания всегда блокируется модальным циклом сообщений.
  6. Независимо от того, является ли скачивание синхронным или асинхронным, моникер возвращается из IMoniker::BindToObject, а браузер получает запрошенный инициализированный объект.

  7. Браузер запрашивает IOleObject и размещает объект в виде объекта Document. (На этом этапе объект может быть инициализирован не полностью, но достаточно для отображения чего-то полезного. В этом случае скачивание продолжается в фоновом режиме.)