Como a associação assíncrona e o armazenamento funcionam
O armazenamento assíncrono aprimora a especificação de armazenamento estruturado COM para dar suporte ao download de objetos de armazenamento em redes de link lento de alta latência, como a Internet. O armazenamento assíncrono funciona em conjunto com monikers assíncronos para fornecer um comportamento completo de associação assíncrona.
Objeto de documento inserido em uma página da Web
Quando um usuário clica em um link que representa um documento inserido em uma página da Web, ocorrem os seguintes eventos:
O navegador chama a função MkParseDisplayName , passando a URL do link.
MkParseDisplayName analisa a URL, cria um moniker assíncrono correspondente e retorna um ponteiro para a interface IMoniker do moniker .
O navegador chama IsAsyncMoniker para determinar se o moniker é assíncrono, cria um contexto de associação, registra a interface IBindStatusCallback com o contexto de associação, somente se o moniker é assíncrono e chama IMoniker::BindToObject, passando o contexto de associação.
O moniker é associado ao objeto e o consulta para a interface IPersistMoniker , que indica se o objeto dá suporte à associação e ao armazenamento assíncronos. Se o objeto retornar um ponteiro para IPersistMoniker:
- O moniker de URL chama IPersistMoniker::Load, passando seu próprio ponteiro IMoniker para o objeto .
- O objeto modifica o contexto de associação, escolhe se deseja um armazenamento de bloqueio ou não, registra seu próprio IBindStatusCallback e chama IMoniker::BindToStorage no ponteiro que recebeu por meio de IPersistMoniker::Load.
- O moniker cria um armazenamento assíncrono, mantém uma referência à interface IFillLockBytes do objeto wrapper, registra a interface IProgressNotify no armazenamento raiz e chama IPersistStorage::Load, passando o ponteiro IStorage do armazenamento assíncrono. À medida que os dados chegam (em um thread em segundo plano), o moniker chama IFillLockBytes para preencher o ILockBytes no arquivo temporário.
- O objeto lê dados do armazenamento e retorna de IPersistMoniker::Load quando recebe dados suficientes para se considerar inicializado. Se o objeto tentar ler dados que ainda não foram baixados, o downloader receberá uma notificação em IProgressNotify. Dentro do método IProgressNotify::OnProgress , o thread de download é bloqueado em um loop de mensagem modal ou faz com que o armazenamento assíncrono retorne E_PENDING, dependendo se o objeto solicitou um armazenamento de bloqueio ou não bloqueado.
Se o objeto não implementar IPersistMoniker, o moniker consultará IPersistStorage, o que indica que o estado persistente do objeto é armazenado em um objeto de armazenamento. Se o objeto retornar um ponteiro para IPersistStorage:
- O Moniker chama IMoniker::BindToStorage em si mesmo, solicitar um IStorage de bloqueio (porque o objeto não tem reconhecimento assíncrono), cria um armazenamento assíncrono, mantém uma referência à interface IFillLockBytes do objeto wrapper, registra a interface IProgressNotify no armazenamento raiz e chama IPersistStorage::Load, passando o ponteiro IStorage do armazenamento assíncrono. À medida que os dados chegam (em um thread em segundo plano), o moniker chama IFillLockBytes para preencher o ILockBytes no arquivo temporário.
- O objeto lê dados do armazenamento e retorna de IPersistStorage::Load quando recebe dados suficientes para se considerar inicializado. Se o objeto tentar ler dados que ainda não foram baixados, ele receberá uma notificação em IProgressNotify. Dentro do método IProgressNotify::OnProgress , o thread de download sempre é bloqueado em um loop de mensagem modal.
Independentemente de o download ser síncrono ou assíncrono, o moniker retorna de IMoniker::BindToObject e o navegador recebe o objeto inicializado solicitado.
O navegador consulta IOleObject e hospeda o objeto como um objeto document. (Neste ponto, o objeto pode não ser inicializado completamente, mas o suficiente para exibir algo útil; nesse caso, o download continua em segundo plano.)