Asynchronous storage supports two storage modes: blocking and nonblocking, which a client (either a browser or the object itself) can specify by returning BINDF_ASYNCSTORAGE from the moniker's call to IBindStatusCallback::GetBindInfo. If a client specifies BINDF_ASYNCSTORAGE, it receives a pointer to a nonblocking asynchronous storage. Otherwise, it receives a pointer to a blocking asynchronous storage. Even if the client does not request an asynchronous binding operation (by not registering IBindStatusCallback with the bind context), the moniker still returns a blocking asynchronous storage, enabling progressive loading for legacy applications.
In nonblocking mode, an asynchronous storage returns E_PENDING when data is unavailable. Upon receiving this message, the client waits for notification that additional data is available before trying again to download it.
In blocking mode, instead of returning E_PENDING, the asynchronous storage blocks the call until new data is available, then unblocks the call and returns the new data. The client must be ready to receive the data. While the thread is blocked, data already passed to the client is fully available to the user.
Blocking mode is necessary because clients unaware of asynchronous storage will not recognize E_PENDING and will assume that an unrecoverable error has occurred. Blocking asynchronous storage enables existing clients to do progressive rendering.