Udostępnij za pośrednictwem


Wykonywanie operacji asynchronicznej

SQL Server Zezwala aplikacjom do wykonywania operacji asynchronicznych bazy danych.Przetwarzanie asynchroniczne umożliwia metod do niezwłocznego zwrotu bez zablokowania na wywołania wątek.Dzięki temu wiele możliwości i elastyczność wielowątkowość, bez konieczności korzystania z projektanta jawnie tworzyć wątków lub obsługę synchronizacji.Aplikacje żądanie przetwarzania asynchronicznego podczas inicjowania połączenia z bazą danych lub w wyniku wykonania polecenia inicjowania.

Otwieranie i zamykanie połączenia bazy danych

Podczas korzystania z SQL Server macierzystego klienta dostawca OLE DB, aplikacje zaprojektowane w celu zainicjowania danych obiekt źródłowy asynchronicznie zestaw DBPROPVAL_ASYNCH_INITIALIZE bit we właściwość DBPROP_INIT_ASYNCH przed do telefonicznej IDBInitialize::Initialize.Gdy ta właściwość jest zestaw, Dostawca niezwłocznie zwraca wywołanie zainicjować z S_OK, jeśli operacja została wykonana natychmiast lub DB_S_ASYNCHRONOUS, jeśli kontynuuje inicjację asynchronicznie.Applications can query for the IDBAsynchStatus or ISSAsynchStatus interface on the data source object, and then call IDBAsynchStatus::GetStatus or ISSAsynchStatus::WaitForAsynchCompletion to get the status of the initialization.

Ponadto właściwość SSPROP_ISSAsynchStatus został dodany do zestaw właściwości DBPROPSET_SQLSERVERROWSET.Dostawców obsługujących ISSAsynchStatus interfejs musi implementować właściwość ta wartość VARIANT_TRUE.

IDBAsynchStatus::Abort lub ISSAsynchStatus::Abort może być wywołana anulować asynchronicznych zainicjować wywołania.Konsument musi jawnie zażądać asynchronicznego inicjowania źródła danych.W przeciwnym razie IDBInitialize::Initialize nie powróci do danych obiekt źródłowy jest w pełni zainicjowany.

Ostrzeżenie

Nie można wywołać obiekty źródło danych używane dla puli połączeń ISSAsynchStatus interfejs w SQL Server macierzystego klienta OLE DB dostawca.ISSAsynchStatus interfejs nie jest narażony obiektów źródło danych w puli.

Jeśli aplikacja jawnie wymusza użycie silnika kursor IOpenRowset::OpenRowset i IMultipleResults::GetResult nie obsługuje przetwarzania asynchronicznego.

Ponadto, nie można wywołać biblioteki dll obiektów proxy/stub zdalnych (w programie MDAC 2.8) ISSAsynchStatus interfejs w SQL Server macierzystego klienta.ISSAsynchStatus interfejs nie jest dostępny za pośrednictwem usług zdalnych.

Składniki usługi nie obsługują ISSAsynchStatus.

Wykonanie i inicjowania zestawu wierszy

Aplikacje zaprojektowane asynchronicznie otworzyć wynik z wykonanie polecenia zestaw DBPROPVAL_ASYNCH_INITIALIZE bit we właściwość DBPROP_ROWSET_ASYNCH.Gdy zestaw tego bitu przed do telefonicznej IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset lub IMultipleResults::GetResult, riid należy ustawić argument IID_IDBAsynchStatus, IID_ISSAsynchStatus lub IID_IUnknown.

Metoda zwraca się bezpośrednio z S_OK, po zakończeniu inicjowania zestawu zestaw wierszy natychmiast lub z DB_S_ASYNCHRONOUS, jeśli nadal zestawu zestaw wierszy inicjowanie asynchronicznie, z ppRowset Ustaw żądany interfejs na zestawie zestaw wierszy.Dla SQL Server macierzystego klienta dostawca OLE DB, ten interfejs może być tylko IDBAsynchStatus lub ISSAsynchStatus.Dopóki zestawu zestaw wierszy jest w pełni zainicjowany, ten interfejs zachowuje się jakby był w stanie wstrzymania i telefonicznej QueryInterface dla interfejsów innych niż IID_IDBAsynchStatus lub IID_ISSAsynchStatus może zwrócić E_NOINTERFACE.Chyba że konsument wyraźnie zażąda przetwarzania asynchronicznego, synchronicznie inicjowania zestawu zestaw wierszy.Wszystkie żądane interfejsy są dostępne, gdy IDBAsynchStaus::GetStatus lub ISSAsynchStatus::WaitForAsynchCompletion zwraca ze wskazaniem, że operacja asynchroniczna została zakończona.Oznacza to że zestawu zestaw wierszy zostanie całkowicie wypełniony, ale jest kompletne i w pełni funkcjonalny.

Jeśli wykonane polecenie nie zwraca zestawu zestaw wierszy, nadal zwraca niezwłocznie z obiektem, który obsługuje IDBAsynchStatus.

Jeśli trzeba uzyskać wiele wyniki z wykonywanie poleceń asynchronicznych, należy:

  • Przed wykonaniem polecenia, należy ustawić bit DBPROPVAL_ASYNCH_INITIALIZE właściwość DBPROP_ROWSET_ASYNCH.

  • Wywołanie ICommand::Execute, a żądanie IMultipleResults.

IDBAsynchStatus i ISSAsynchStatus interfejsów następnie uzyskuje się przez badanie wiele wyniki interfejs używając QueryInterface.

Po zakończeniu wykonywania polecenia wykonywane, IMultipleResults może być używany jako normalne, z jednym wyjątkiem od synchroniczne przypadek: DB_S_ASYNCHRONOUS mogą być zwracane w takim przypadek IDBAsynchStatus lub ISSAsynchStatus można określić, po zakończeniu operacji.

Przykłady

W następującym przykładzie aplikacja wywołuje metoda nieblokujące innych procesów jest i zwraca wyniki przetwarzania.ISSAsynchStatus::WaitForAsynchCompletion czeka na obiekt zdarzenie wewnętrznego, dopóki jest wykonywane asynchronicznie wykonywanie operacji lub na czas określony przez dwMilisecTimeOut jest przekazywana.

// 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 będzie czekał na obiekt zdarzenie wewnętrznego jest wykonywane asynchronicznie wykonywanie operacji lub dwMilisecTimeOut przekazana wartość.

Poniższy przykład ilustruje przetwarzanie asynchroniczne z wielu zestawów wyników:

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 uniknąć blokowania, klient można sprawdzić stan uruchamianie asynchronicznych operacji, jak w poniższym przykładzie:

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

Poniższy przykład ilustruje, jak można anulować operacji asynchronicznej aktualnie uruchomione:

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