MDAC 2.5 SDK - OLE DB Programmer's Reference
Chapter 17: Asynchronous Processing
Consumers that want to asynchronously open a rowset set the DBPROPVAL_ASYNCH_INITIALIZE bit in the DBPROP_ROWSET_ASYNCH property. When setting this bit prior to calling ICommand::Execute, IOpenRowset::OpenRowset, IDBSchemaRowset::GetRowset, IRowPosition::GetRowset, IColumnsRowset::GetColumnsRowset, IMultipleResults::GetResult, ISourcesRowset::GetSourcesRowset, or any other method that returns a rowset, riid must be set to IID_IDBAsynchStatus, IID_IConnectionPointContainer, or IID_IUnknown.
The method returns immediately with S_OK if the rowset initialization completes immediately, or with DB_S_ASYNCHRONOUS if the rowset will continue initializing asynchronously, with ppRowset set to the requested interface on the rowset. Until the rowset is fully initialized, it behaves as if it is in a zombie state, and calling QueryInterface for interfaces other than IID_IConnectionPointContainer or IID_IDBAsynchStatus may return E_NOINTERFACE. Unless the consumer explicitly requests asynchronous processing, the rowset is initialized synchronously. All requested interfaces are available when the method requesting the rowset returns. This does not necessarily mean that the rowset is fully populated, but it must be complete and fully functional.
If the executed command does not return a rowset, it still returns immediately with an object that supports IDBAsynchStatus.
If output parameters are specified on the command, they usually are not available until the rowset is completely initialized and might not be available until all of the data has been read from the rowset.
To obtain multiple results, the consumer sets the DBPROPVAL_ASYNCH_INITIALIZE bit of the DBPROP_ROWSET_ASYNCH property prior to executing the command and then calls ICommand::Execute with DBPROP_IMultipleResults set to VARIANT_TRUE and riid set to IID_IMultipleResults; and finally, the consumer calls IMultipleResults::GetResult with riid set to IID_IDBAsynchStatus or IID_IConnectionPointContainer to retrieve individual results asynchronously. When consumers request a multiple-results object from ICommand::Execute, providers should return immediately with the multiple-results object and save processing until the consumer calls IMultipleResults::GetResult.
To cancel creation of the rowset, the consumer can call IDBAsynchStatus::Abort or can simply release all interfaces on the rowset. Once the rowset's reference count goes to zero, any asynchronous processing is canceled and the rowset is released. Calling IDBAsynchStatus::Abort still requires releasing the interface.