Sdílet prostřednictvím


Provádění asynchronních operací

Platí na:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytický platformový systém (PDW)SQL databáze v Microsoft Fabric

Stáhnout ovladač OLE DB

SQL Server umožňuje aplikacím provádět asynchronní databázové operace. Asynchronní zpracování umožňuje metodám okamžitě vrátit se bez blokování volajícího vlákna. To umožňuje velkou část výkonu a flexibility multithreadingu, aniž by vývojář musel explicitně vytvářet vlákna nebo řešit synchronizaci. Aplikace požadují asynchronní zpracování při inicializaci připojení k databázi nebo při inicializaci výsledku z provedení příkazu.

Otevírání a uzavření databázového spojení

Při použití ovladače OLE DB pro SQL Server mohou aplikace navržené pro asynchronní inicializaci objektu datového zdroje nastavit DBPROPVAL_ASYNCH_INITIALIZE bit ve vlastnosti DBPROP_INIT_ASYNCH před zavoláním IDBInitialize::Initialize. Když je tato vlastnost nastavena, poskytovatel se ihned vrátí z volání do Initialize buď s S_OK, pokud byla operace okamžitě dokončena, nebo DB_S_ASYNCHRONOUS, pokud inicializace pokračuje asynchronně. Aplikace mohou vyhledávat rozhraní IDBAsynchStatus nebo ISSAsynchStatus na datovém zdrojovém objektu a poté volat IDBAsynchStatus::GetStatus nebo ISSAsynchStatus::WaitForAsynchCompletion pro získání stavu inicializace.

Kromě toho byla do sady DBPROPSET_SQLSERVERROWSET vlastností přidána SSPROP_ISSAsynchStatus vlastnost. Poskytovatelé podporující rozhraní ISSAsynchStatus musí tuto vlastnost implementovat s hodnotou VARIANT_TRUE.

IDBAsynchStatus::Abort nebo ISSAsynchStatus::Abort lze vyvolat k zrušení asynchronního Initialize hovoru. Spotřebitel musí výslovně požádat o inicializaci asynchronního datového zdroje. Jinak IDBInitialize::Initialize se nevrátí, dokud není objekt zdrojového data zcela inicializován.

Poznámka:

Objekty zdrojů dat používané pro pooling spojení nemohou volat rozhraní ISSAsynchStatus v OLE DB Driver for SQL Server. Rozhraní ISSAsynchStatus není vystaveno pro sdílené objekty datových zdrojů.

Pokud aplikace výslovně vyžaduje použití kurzorového enginu, IOpenRowset::OpenRowset a IMultipleResults::GetResult nepodporují asynchronní zpracování.

Navíc vzdálený proxy/stub dll (v MDAC 2.8) nemůže volat rozhraní ISSAsynchStatus v OLE DB Driver for SQL Server. Rozhraní ISSAsynchStatus není vystaveno vzdáleným režimem.

Servisní komponenty nepodporují ISSAsynchStatus.

Provádění a inicializace řádků

Aplikace navržené k asynchronnímu otevření výsledku z provedení příkazu mohou nastavit DBPROPVAL_ASYNCH_INITIALIZE bit ve vlastnosti DBPROP_ROWSET_ASYNCH. Při nastavení tohoto bitu před voláním IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset nebo IMultipleResults::GetResult musí být argument riid nastaven na IID_IDBAsynchStatus, IID_ISSAsynchStatus nebo IID_IUnknown.

Metoda okamžitě vrátí S_OK, pokud inicializace řádků je okamžitě dokončena, nebo s DB_S_ASYNCHRONOUS, pokud se sada pokračuje v asynchronní inicializaci, přičemž ppRowset je nastaven na požadované rozhraní na řádku. Pro ovladač OLE DB pro SQL Server může být toto rozhraní pouze IDBAsynchStatus nebo ISSAsynchStatus. Dokud není sada řádků plně inicializována, toto rozhraní se chová, jako by bylo ve stavu pozastavení, a volání QueryInterface pro rozhraní jiné než IID_IDBAsynchStatus nebo IID_ISSAsynchStatus může vrátit E_NOINTERFACE. Pokud spotřebitel výslovně nepožaduje asynchronní zpracování, je řádková sada inicializována synchronně. Všechna požadovaná rozhraní jsou dostupná, když IDBAsynchStatus::GetStatus nebo ISSAsynchStatus::WaitForAsynchCompletion vrátí s indikací, že asynchronní operace je dokončena. To nutně neznamená, že je řádková sada plně obsazená, ale je kompletní a plně funkční.

Pokud vykonaný příkaz nevrátí sadu řádků, stále se okamžitě vrátí s objektem, který podporuje IDBAsynchStatus.

Pokud potřebujete získat více výsledků z asynchronního provádění příkazů, měli byste:

  • Nastavte DBPROPVAL_ASYNCH_INITIALIZE bit vlastnosti DBPROP_ROWSET_ASYNCH před vykonáním příkazu.

  • Zavolejte ICommand::Execute a požádejte o IMultipleResults.

Rozhraní IDBAsynchStatus a ISSAsynchStatus lze následně získat dotazováním rozhraní s více výsledky pomocí QueryInterface.

Po dokončení příkazu lze IMultipleResults použít normálně, s jednou výjimkou ze synchronního případu: DB_S_ASYNCHRONOUS může být vrácen, v takovém případě lze použít IDBAsynchStatus nebo ISSAsynchStatus k určení dokončení operace.

Examples

V následujícím příkladu aplikace zavolá neblokující metodu, provede další zpracování a poté se vrátí k zpracování výsledků. ISSAsynchStatus::WaitForAsynchCompletion čeká na interním objektu události, dokud není asynchronně vykonávaná operace dokončena nebo dokud neuplyne čas určený 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 čeká na interní objekt události, dokud není asynchronně vykonávající operace dokončena nebo dokud není předána hodnota dwMilisecTimeOut .

Následující příklad ukazuje asynchronní zpracování s více sadami výsledků:

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();  
   }  
}  

Aby se zabránilo blokování, klient může zkontrolovat stav běžící asynchronní operace, jak je uvedeno v následujícím příkladu:

// 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();  
}  

Následující příklad ukazuje, jak můžete zrušit právě běžící asynchronní operaci:

// 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);  
}  

Viz také

OLE DB Driver for SQL Server Features
Vlastnosti a chování řádků
ISSAsynchStatus (OLE DB)