Udostępnij za pośrednictwem


Wykonywanie operacji asynchronicznych

SQL Server Zezwala aplikacjom na wykonywanie operacji asynchronicznej bazy danych.Przetwarzanie asynchroniczne umożliwia metody, aby zwrócić natychmiast, bez blokowania na wywołania wątek.Dzięki temu wiele możliwości i elastyczność wielowątkowości, bez konieczności deweloper jawnie tworzyć wątków lub obsługiwać synchronizację.Aplikacje żądania asynchroniczne przetwarzania podczas inicjowania połączenia z bazą danych lub podczas inicjowania w wyniku wykonania polecenia.

Otwieranie i zamykanie połączenia bazy danych

Podczas korzystania z SQL Server Macierzystego dostawca klient OLE DB, aplikacje zaprojektowane do zainicjowania danych obiekt źródłowy asynchronicznie można ustawić DBPROPVAL_ASYNCH_INITIALIZE, bit we właściwość DBPROP_INIT_ASYNCH wprowadzenia telefonicznej IDBInitialize::Initialize.Gdy ta właściwość jest zestaw, dostawca natychmiast zwraca wywołanie Inicjowanie 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 ISSAsynchStatusinterface on the data source object, and then call IDBAsynchStatus::GetStatus orISSAsynchStatus::WaitForAsynchCompletion to get the status of the initialization.

Ponadto właściwość SSPROP_ISSAsynchStatus został dodany do zestaw właściwości DBPROPSET_SQLSERVERROWSET.Dostawcy, które obsługują ISSAsynchStatus interfejs musi implementować tej właściwość wartość VARIANT_TRUE.

IDBAsynchStatus::Abort or ISSAsynchStatus::Abort można wywołać, aby anulować asynchronicznego Inicjowanie wywołanie.Konsument musi zażądać jawnie asynchroniczny inicjowania urządzenie źródłowe danych.W przeciwnym razie IDBInitialize::Initialize nie zwraca, aż obiekt urządzenie źródłowe danych jest całkowicie zainicjowany.

Uwaga

Nie można wywołać obiektów urządzenie źródłowe danych używane do tworzenia i utrzymywania puli połączeń ISSAsynchStatus interfejsSQL Server Macierzystego dostawca klient OLE DB. The ISSAsynchStatus interfejs is not exposed for pooled data urządzenie źródłowe objects.

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

Ponadto nie można wywołać dll obiektów proxy/procedur wejścia usług zdalnych (w programie MDAC 2.8) ISSAsynchStatus interfejsSQL Server Macierzysta klient. The ISSAsynchStatus interfejs is not exposed through remoting.

Składniki usługa nie są obsługiwane. ISSAsynchStatus.

Wykonywanie i inicjowania zestawu zestaw wierszy

Aplikacje zaprojektowane asynchronicznie otworzyć wynik z wykonanie polecenia może zestaw the DBPROPVAL_ASYNCH_INITIALIZE bit we właściwość DBPROP_ROWzestaw_ASYNCH.Jeśli to ustawienie przed telefonicznej bit IDBInitialize::Initialize, ICommand::wykonać, IOpenRowset::OpenRowset or IMultipleResults::GetResult, the riid Argument musi być równa IID_IDBAsynchStatus, IID_ISSAsynchStatus lub IID_IUnknown.

Metoda zwraca się bezpośrednio z S_OK, po zakończeniu inicjowania zestawu wierszy natychmiast lub z DB_S_ASYNCHRONOUS, jeśli ten zestaw wierszy w dalszym ciągu inicjowania asynchronicznie, z ppRowset Ustaw żądany interfejs na zestawie wierszy. Dla SQL Server Macierzysta klient OLE DB, tego interfejs mogą być tylko IDBAsynchStatus or ISSAsynchStatus.Dopóki ten zestaw wierszy jest w pełni zainicjowany, ten interfejs zachowuje się tak, jakby był w stanie wstrzymania i telefonicznej Metoda QueryInterface wykonana interfejsów innych niż IID_IDBAsynchStatus or IID_ISSAsynchStatus może zwracać E_NOINTERFACE.Chyba że konsument żąda jawnie przetwarzania asynchronicznego, synchronicznie inicjowania zestawu zestaw wierszy.Wszystkie żądane interfejsy są dostępne, gdy IDBAsynchStaus::GetStatus or ISSAsynchStatus::WaitForAsynchCompletion zwraca ze wskazaniem, że operacja asynchroniczna została zakończona.To niekoniecznie oznacza że zestawu zestaw wierszy zostanie całkowicie wypełniony, ale jest kompletny i w pełni funkcjonalny.

Polecenie wykonane nie zwraca zestawu zestaw wierszy, nadal powraca bezpośrednio z obiektem, który obsługuje IDBAsynchStatus.

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

  • Ustaw bit DBPROPVAL_ASYNCH_INITIALIZE właściwość DBPROP_ROWSET_ASYNCH przed wykonaniem polecenia.

  • Wywołanie ICommand::wykonaći żądania IMultipleResults.

The IDBAsynchStatus and ISSAsynchStatus interfaces can then be obtained by querying the multiple wyniki interfejs using QueryInterface.

Kiedy polecenie zakończono wykonywanie, IMultipleResults mogą być używane jako normalne, z jednym wyjątkiem od synchroniczne przypadek: DB_S_ASYNCHRONOUS może być zwrócona, w których przypadek IDBAsynchStatus or ISSAsynchStatus można ustalić, kiedy dana operacja jest zakończona.

Przykłady

W poniższym przykładzie aplikacja wywołuje metoda bez blokowania, ma kilka innych procesów i zwraca do przetworzenia wyniki.ISSAsynchStatus::WaitForAsynchCompletion czeka na czas określony przez lub obiektu Zdarzenie wewnętrzne, dopóki nie jest wykonywane asynchronicznie wykonywanie operacjidwMilisecTimeOut jest przekazywany.

// 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 oczekuje na obiekt wewnętrzny zdarzenie, dopóki nie jest wykonywane asynchronicznie wykonywanie operacji lub dwMilisecTimeOut wartość jest przekazywana.

W poniższym przykładzie pokazano przetwarzania asynchronicznego 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 zapobiec blokowaniu, klient może sprawdzić stan bieżących 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();
}

W poniższym przykładzie pokazano, w jaki sposób można anulować operację aktualnie uruchomiona asynchronicznych:

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