Megosztás:


Aszinkron műveletek végrehajtása

Vonatkozik a következőkre:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalitikai Platform System (PDW)SQL adatbázis a Microsoft Fabric-ben

OLE DB-illesztő letöltése

Az SQL Server lehetővé teszi az alkalmazások aszinkron adatbázis-műveletek végrehajtását. Az aszinkron feldolgozás lehetővé teszi, hogy a metódok azonnal visszatérjenek anélkül, hogy blokkolnák a hívó szálat. Ez lehetővé teszi a többszálas munka erejének és rugalmasságának nagy részét anélkül, hogy a fejlesztőnek kifejezetten szálakat kellene létrehoznia vagy szinkronizálnia kellene. Az alkalmazások aszinkron feldolgozást kérnek adatbázis-kapcsolat inicializálásakor, vagy egy parancs végrehajtásának eredményének inicializálásakor.

Adatbázis-kapcsolat megnyitása és lezárása

Az OLE DB Driver SQL Server használatakor az adatforrás objektum aszinkron inicializálására tervezett alkalmazások beállíthatják a DBPROPVAL_ASYNCH_INITIALIZE bitet a DBPROP_INIT_ASYNCH tulajdonságban, mielőtt IDBInitialize::Initialize hívják. Amikor ezt a tulajdonságot beállítják, a szolgáltató azonnal visszatér a hívásból inicializálásra , vagy S_OK-vel, ha a művelet azonnal befejeződött, vagy DB_S_ASYNCHRONOUS, ha az inicializáció aszinkron módon folytatódik. Az alkalmazások lekérdezhetik az IDBAsynchStatus vagy ISSAsynchStatus interfészt az adatforrás objektumon, majd az IDBAsynchStatus::GetStatus vagy ISSAsynchStatus:::WaitForAsynchCompletion fájlokat hívják, hogy megkapják az inicializáció állapotát.

Ezen felül a SSPROP_ISSAsynchStatus tulajdonságot is hozzáadták a DBPROPSET_SQLSERVERROWSET tulajdonsághalmazhoz. Az ISSAsynchStatus interfészt támogató szolgáltatóknak ezt a tulajdonságot VARIANT_TRUE értékkel kell megvalósítaniuk.

Az IDBAsynchStatus::Abort vagy az ISSAsynchStatus::Abort megszólalható, hogy lemondják az aszinkron Initialize hívást. A fogyasztónak kifejezetten kérnie kell az Aszinkron Adatforrás Inicializációt. Ellenkező esetben az IDBInitialize::Initialize csak akkor tér vissza, ha az adatforrás objektumot teljesen inicializálják.

Megjegyzés:

A kapcsolat poolinghez használt adatforrás objektumok nem hívhatják az OLE DB SQL Server ISSAsynchStatus interfészét. Az ISSAsynchStatus interfész nem van kitéve a csoportos adatforrás objektumok számára.

Ha egy alkalmazás kifejezetten kényszeríti a kurzormotor használatát, az IOpenRowset::OpenRowset és az IMultipleResults::GetResult nem támogatják az aszinkron feldolgozást.

Ezen felül a távirányító proxy/stub dll (MDAC 2.8-ban) nem tudja hívni az OLE DB Driver for SQL Server ISSAsynchStatus interfészét. Az ISSAsynchStatus interfész nem lesz elérhető távirányítás közben.

A szolgáltatási komponensek nem támogatják az ISSAsynchStatus-t.

Végrehajtás és sorhalmaz inicializálása

Az alkalmazások, amelyek aszinkron módon nyitják meg a parancs végrehajtásából származó eredményt, beállíthatják a DBPROP_ROWSET_ASYNCH tulajdonság DBPROPVAL_ASYNCH_INITIALIZE bitjét. Amikor ezt a bitet beállítjuk IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset vagy IMultipleResults::GetResult hívása előtt, a riid argumentumot be kell állítani IID_IDBAsynchStatus, IID_ISSAsynchStatus vagy IID_IUnknown-re.

A metódus azonnal visszatér S_OK-vel, ha a sorhalmaz inicializálása azonnal befejeződik, vagy DB_S_ASYNCHRONOUS-vel, ha a sorhalmaz aszinkron módon inicializálódik, a ppRowset pedig a sorhalmazon a kért interfészre van beállítva. Az SQL Server OLE DB illesztőprogramja esetén ez az interfész csak IDBAsynchStatus vagy ISSAsynchStatus lehet. Amíg a sorhalmaz teljesen inicializálódik, ez az interfész úgy viselkedik, mintha felfüggesztett állapotban lenne, és a QueryInterface hívása más interfészekre, mint IID_IDBAsynchStatus vagy IID_ISSAsynchStatus , E_NOINTERFACE visszavezethet. Hacsak a fogyasztó nem kér kifejezetten aszinkron feldolgozást, a sorhalmaz szinkron inicializálásra kerül. Minden kért interfész elérhető, amikor az IDBAsynchStatus::GetStatus vagy az ISSAsynchStatus:::WaitForAsynchCompletion visszatér, jelezve, hogy az aszinkron működés befejeződött. Ez nem feltétlenül jelenti azt, hogy a sorhalmaz teljesen fel van töltve, de teljes és teljesen funkcionális.

Ha a végrehajtott parancs nem ad vissza sorhalmazt, akkor is azonnal visszajön egy olyan objektummal, amely támogatja az IDBAsynchStatus-t.

Ha több eredményt kell elérned aszinkron parancsvégrehajtással, akkor a következőket kell megszerezned:

  • Állítsd be a DBPROP_ROWSET_ASYNCH tulajdonság DBPROPVAL_ASYNCH_INITIALIZE bitjét, mielőtt végrehajtanád a parancsot.

  • Hívd az ICommand::Execute-t, és kérd az IMultipleResults-t.

Az IDBAsynchStatus és ISSAsynchStatus interfészek ezután a több eredmény interfészének lekérdezésével szerezhetők be a QueryInterface-en.

Amikor a parancs befejezte a végrehajtást, az IMultipleResults normál módon használható, egy kivétellel a szinkron esetből: DB_S_ASYNCHRONOUS vissza lehet térni, ilyenkor IDBAsynchStatus vagy ISSAsynchStatus segítségével meghatározhatjuk, mikor fejezte be a műveletet.

Példák

A következő példában az alkalmazás nem blokkoló módszert hív, más feldolgozást végez, majd visszatér az eredmények feldolgozásához. Az ISSAsynchStatus::WaitForAsynchCompletion a belső eseményobjektumra vár, amíg az aszinkron végrehajtású művelet el nem fejeződik, vagy a dwMilisecTimeOut által megadott idő át nem kerül.

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

Az ISSAsynchStatus::WaitForAsynchCompletion a belső eseményobjektumra vár, amíg az aszinkron végrehajtású művelet el nem fejeződik, vagy addig ad át a dwMilisecTimeOut értéket.

Az alábbi példa aszinkron feldolgozást mutat több eredményhalmazsal:

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

A blokkolás megelőzése érdekében a kliens ellenőrizheti egy futó aszinkron művelet állapotát, mint a következő példa:

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

Az alábbi példa bemutatja, hogyan lehet megszüntetni a jelenleg futó aszinkron műveletet:

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

Lásd még:

OLE DB Driver for SQL Server Features
Sorhalmaz tulajdonságai és viselkedései
ISSAsynchStatus (OLE DB)