Asynchronous Command Execution and Rowset Generation

Consumers that want to asynchronously open a rowset set the DBPROPVAL_ASYNCH_INITIALIZE bit in the DBPROP_ROWSET_ASYNCH property. When setting this bit, it is permitted to ask for IConnectionPointContainer to obtain IID_IDBAsynchNotify, or IID_IDBAsynch, or IID_IUnknown (and QueryInterface for either of the other two interfaces).

Additionally, if the consumer calls Execute, OpenRowset, GetRowset, GetColumnsRowset, GetResult, GetSourcesRowset, or any other method that returns a rowset, riid must be set to IID_IDBAsynchStatus or IID_IConnectionPointContainer.

The method returns immediately with S_OK if the rowset initialization completes immediately, or 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 are usually not available until the rowset is completely initialized, and may 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, then calls ICommand::Execute with riid set to IID_IMultipleResults, and finally IMultipleResults::GetResult with riid set to IID_IDBAsynchStatus to retrieve individual results asynchronously. When consumers request a multiple-results object from Execute, providers should return immediately with the multiple-results object, and save processing until the consumer calls GetResult.

To cancel creation of the rowset, the consumer may call IDBAsynchStatus::Abort, or may 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.