Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
SQL Server consente alle applicazioni di eseguire operazioni asincrone del database. L'elaborazione asincrona consente ai metodi di restituire immediatamente senza bloccare il thread chiamante. Ciò consente gran parte della potenza e della flessibilità del multithreading, senza che lo sviluppatore crei in modo esplicito thread o gestisca la sincronizzazione. Le applicazioni richiedono l'elaborazione asincrona durante l'inizializzazione di una connessione di database o durante l'inizializzazione del risultato dall'esecuzione di un comando.
Apertura e chiusura di una connessione di database
Quando si usa il provider OLE DB di SQL Server Native Client, le applicazioni progettate per inizializzare un oggetto origine dati in modo asincrono possono impostare il bit di DBPROPVAL_ASYNCH_INITIALIZE nella proprietà DBPROP_INIT_ASYNCH prima di chiamare IDBInitialize::Initialize. Quando questa proprietà è impostata, il provider restituisce immediatamente dalla chiamata a Initialize con S_OK, se l'operazione è stata completata immediatamente o DB_S_ASYNCHRONOUS, se l'inizializzazione continua in modo asincrono. Le applicazioni possono eseguire query per l'interfaccia IDBAsynchStatus o ISSAsynchStatusnell'oggetto origine dati e quindi chiamare IDBAsynchStatus::GetStatus oISSAsynchStatus::WaitForAsynchCompletion per ottenere lo stato dell'inizializzazione.
Inoltre, la proprietà SSPROP_ISSAsynchStatus è stata aggiunta al set di proprietà DBPROPSET_SQLSERVERROWSET. I provider che supportano l'interfaccia ISSAsynchStatus devono implementare questa proprietà con un valore di VARIANT_TRUE.
IDBAsynchStatus::Abort o ISSAsynchStatus::Abort può essere chiamato per annullare la chiamata asincrona Initialize . Il consumer deve richiedere in modo esplicito l'inizializzazione asincrona dell'origine dati. In caso contrario, IDBInitialize::Initialize non restituisce finché l'oggetto origine dati non viene completamente inizializzato.
Annotazioni
Gli oggetti origine dati usati per il pool di connessioni non possono chiamare l'interfaccia ISSAsynchStatus nel provider OLE DB di SQL Server Native Client. L'interfaccia ISSAsynchStatus non è esposta per gli oggetti origine dati in pool.
Se un'applicazione forza esplicitamente l'uso del motore di cursore, IOpenRowset::OpenRowset e IMultipleResults::GetResult non supporterà l'elaborazione asincrona.
Inoltre, la dll proxy/stub remoting (in MDAC 2.8) non può chiamare l'interfaccia ISSAsynchStatus in SQL Server Native Client. L'interfaccia ISSAsynchStatus non viene esposta tramite la comunicazione remota.
I componenti del servizio non supportano ISSAsynchStatus.
Esecuzione e inizializzazione del set di righe
Le applicazioni progettate per aprire in modo asincrono il risultato dall'esecuzione di un comando possono impostare il bit di DBPROPVAL_ASYNCH_INITIALIZE nella proprietà DBPROP_ROWSET_ASYNCH. Quando si imposta questo bit prima di chiamare IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset o IMultipleResults::GetResult, l'argomento riid deve essere impostato su IID_IDBAsynchStatus, IID_ISSAsynchStatus o IID_IUnknown.
Il metodo restituisce immediatamente con S_OK se l'inizializzazione del set di righe viene completata immediatamente o con DB_S_ASYNCHRONOUS se il set di righe continua a inizializzare in modo asincrono, con ppRowset impostato sull'interfaccia richiesta nel set di righe. Per il provider OLE DB di SQL Server Native Client, questa interfaccia può essere solo IDBAsynchStatus o ISSAsynchStatus. Fino a quando il set di righe non viene inizializzato completamente, questa interfaccia si comporta come se fosse in stato sospeso e la chiamata a QueryInterface per interfacce diverse da IID_IDBAsynchStatus o IID_ISSAsynchStatus potrebbe restituire E_NOINTERFACE. A meno che il consumer non richieda in modo esplicito l'elaborazione asincrona, il set di righe viene inizializzato in modo sincrono. Tutte le interfacce richieste sono disponibili quando IDBAsynchStaus::GetStatus o ISSAsynchStatus::WaitForAsynchCompletion restituisce con l'indicazione che l'operazione asincrona è stata completata. Ciò non significa necessariamente che il set di righe sia completamente popolato, ma è completo e completamente funzionante.
Se il comando eseguito non restituisce un set di righe, viene comunque restituito immediatamente con un oggetto che supporta IDBAsynchStatus.
Se è necessario ottenere più risultati dall'esecuzione asincrona dei comandi, è necessario:
Impostare il bit DBPROPVAL_ASYNCH_INITIALIZE della proprietà DBPROP_ROWSET_ASYNCH prima di eseguire il comando.
Chiamare ICommand::Execute e richiedere IMultipleResults.
È quindi possibile ottenere le interfacce IDBAsynchStatus e ISSAsynchStatus eseguendo una query sull'interfaccia di più risultati usando QueryInterface.
Al termine dell'esecuzione del comando, È possibile usare IMultipleResults come di consueto, con un'eccezione del caso sincrono: DB_S_ASYNCHRONOUS può essere restituito, nel qual caso È possibile usare IDBAsynchStatus o ISSAsynchStatus per determinare quando l'operazione è stata completata.
Esempi
Nell'esempio seguente l'applicazione chiama un metodo senza blocco, esegue un'altra elaborazione e quindi restituisce per elaborare i risultati. ISSAsynchStatus::WaitForAsynchCompletion attende l'oggetto evento interno fino a quando non viene eseguita l'operazione in modo asincrono o la quantità di tempo specificata da dwMilisecTimeOut .
// Set the DBPROPVAL_ASYNCH_INITIALIZE bit in the
// DBPROP_ROWSET_ASYNCH property before calling Execute().
DBPROPSET CmdPropset[1];
DBPROP CmdProperties[1];
CmdPropset[0].rgProperties = CmdProperties;
CmdPropset[0].cProperties = 1;
CmdPropset[0].guidPropertySet = DBPROPSET_ROWSET;
// Set asynch mode for command.
CmdProperties[0].dwPropertyID = DBPROP_ROWSET_ASYNCH;
CmdProperties[0].vValue.vt = VT_I4;
CmdProperties[0].vValue.lVal = DBPROPVAL_ASYNCH_INITIALIZE;
CmdProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
hr = pICommandProps->SetProperties(1, CmdPropset);
hr = pICommand->Execute(
pUnkOuter,
IID_ISSAsynchStatus,
pParams,
pcRowsAffected,
(IUnknown**)&pISSAsynchStatus);
if (hr == DB_S_ASYNCHRONOUS)
{
// Do some work here...
hr = pISSAsynchStatus->WaitForAsynchCompletion(dwMilisecTimeOut);
if ( hr == S_OK)
{
hr = pISSAsynchStatus->QueryInterface(IID_IRowset, (void**)&pRowset);
pISSAsynchStatus->Release();
}
}
ISSAsynchStatus::WaitForAsynchCompletion attende l'oggetto evento interno fino a quando non viene eseguita l'operazione in modo asincrono o viene passato il valore dwMilisecTimeOut .
L'esempio seguente mostra l'elaborazione asincrona con più set di risultati:
DBPROP CmdProperties[1];
// Set asynch mode for command.
CmdProperties[0].dwPropertyID = DBPROP_ROWSET_ASYNCH;
CmdProperties[0].vValue.vt = VT_I4;
CmdProperties[0].vValue.lVal = DBPROPVAL_ASYNCH_INITIALIZE;
hr = pICommand->Execute(
pUnkOuter,
IID_IMultipleResults,
pParams,
pcRowsAffected,
(IUnknown**)&pIMultipleResults);
// Use GetResults for ISSAsynchStatus.
hr = pIMultipleResults->GetResult(IID_ISSAsynchStatus, (void **) &pISSAsynchStatus);
if (hr == DB_S_ASYNCHRONOUS)
{
// Do some work here...
hr = pISSAsynchStatus->WaitForAsynchCompletion(dwMilisecTimeOut);
if (hr == S_OK)
{
hr = pISSAsynchStatus->QueryInterface(IID_IRowset, (void**)&pRowset);
pISSAsynchStatus->Release();
}
}
Per evitare il blocco, il client può controllare lo stato di un'operazione asincrona in esecuzione, come nell'esempio seguente:
// Set the DBPROPVAL_ASYNCH_INITIALIZE bit in the
// DBPROP_ROWSET_ASYNCH property before calling Execute().
hr = pICommand->Execute(
pUnkOuter,
IID_ISSAsynchStatus,
pParams,
pcRowsAffected,
(IUnknown**)&pISSAsynchStatus);
if (hr == DB_S_ASYNCHRONOUS)
{
do{
// Do some work...
hr = pISSAsynchStatus->GetStatus(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN, NULL, NULL, &ulAsynchPhase, NULL);
}while (DBASYNCHPHASE_COMPLETE != ulAsynchPhase)
if SUCCEEDED(hr)
{
hr = pISSAsynchStatus->QueryInterface(IID_IRowset, (void**)&pRowset);
}
pIDBAsynchStatus->Release();
}
L'esempio seguente illustra come annullare l'operazione asincrona attualmente in esecuzione:
// Set the DBPROPVAL_ASYNCH_INITIALIZE bit in the
// DBPROP_ROWSET_ASYNCH property before calling Execute().
hr = pICommand->Execute(
pUnkOuter,
IID_ISSAsynchStatus,
pParams,
pcRowsAffected,
(IUnknown**)&pISSAsynchStatus);
if (hr == DB_S_ASYNCHRONOUS)
{
// Do some work...
hr = pISSAsynchStatus->Abort(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN);
}
Vedere anche
Funzionalità di SQL Server Native Client
Proprietà e comportamenti dei set di righe
ISSAsynchStatus (OLE DB)