Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
SQL Server позволяет приложениям выполнять асинхронные операции базы данных. Асинхронная обработка позволяет методам немедленно возвращать данные без блокировки вызывающего потока. Это позволяет использовать большую часть возможностей и гибкости многопоточных операций, не требуя от разработчика явного создания потоков или обработки синхронизации. Приложения запрашивают асинхронную обработку при инициализации подключения к базе данных или при инициализации результата выполнения команды.
Открытие и закрытие подключения к базе данных
При использовании поставщика OLE DB собственного клиента SQL Server приложения, предназначенные для асинхронной инициализации объекта источника данных, могут задать DBPROPVAL_ASYNCH_INITIALIZE бит в свойстве DBPROP_INIT_ASYNCH перед вызовом IDBInitialize::Initialize. Если это свойство задано, поставщик сразу же возвращается из вызова инициализации с помощью S_OK, если операция завершилась немедленно или DB_S_ASYNCHRONOUS, если инициализация продолжается асинхронно. Приложения могут запрашивать интерфейс IDBAsynchStatus или ISSAsynchStatusв объекте источника данных, а затем вызывать IDBAsynchStatus::GetStatus илиISSAsynchStatus::WaitForAsynchCompletion , чтобы получить состояние инициализации.
Кроме того, свойство SSPROP_ISSAsynchStatus добавлено в набор свойств DBPROPSET_SQLSERVERROWSET. Поставщики, поддерживающие интерфейс ISSAsynchStatus , должны реализовать это свойство со значением VARIANT_TRUE.
IdBAsynchStatus::Abort или ISSAsynchStatus::Abort можно вызвать для отмены асинхронного вызова инициализации . Потребитель должен явно запрашивать асинхронную инициализацию источника данных. В противном случае IDBInitialize::Initialize не возвращается, пока объект источника данных не будет полностью инициализирован.
Замечание
Объекты источника данных, используемые для пула подключений, не могут вызывать интерфейс ISSAsynchStatus в поставщике OLE DB собственного клиента SQL Server. Интерфейс ISSAsynchStatus не предоставляется для объектов источника данных в пуле.
Если приложение явно принудительно использует обработчик курсоров, IOpenRowset::OpenRowset и IMultipleResults::GetResult не будет поддерживать асинхронную обработку.
Кроме того, библиотека DLL удаленного взаимодействия с прокси-сервером или заглушкой (в MDAC 2.8) не может вызывать интерфейс ISSAsynchStatus в собственном клиенте SQL Server. Интерфейс ISSAsynchStatus не предоставляется через удаленное взаимодействие.
Компоненты службы не поддерживают ISSAsynchStatus.
Инициализация набора строк и выполнения
Приложения, предназначенные для асинхронного открытия результата выполнения команды, могут задать DBPROPVAL_ASYNCH_INITIALIZE бит в свойстве DBPROP_ROWSET_ASYNCH. При задании этого бита перед вызовом IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset или IMultipleResults::GetResult аргумент riid должен быть задан как IID_IDBAsynchStatus, IID_ISSAsynchStatus или IID_IUnknown.
Метод возвращается немедленно с S_OK, если инициализация набора строк завершается немедленно или с DB_S_ASYNCHRONOUS, если набор строк продолжает инициализировать асинхронно, при этом ppRowset устанавливается на запрошенный интерфейс в наборе строк. Для поставщика OLE DB собственного клиента SQL Server этот интерфейс может быть только IDBAsynchStatus или ISSAsynchStatus. Пока набор строк не будет полностью инициализирован, этот интерфейс работает так, как если бы он был в приостановленном состоянии, а вызов QueryInterface для интерфейсов, отличных от IID_IDBAsynchStatus или IID_ISSAsynchStatus , может возвращать E_NOINTERFACE. Если потребитель явно не запрашивает асинхронную обработку, набор строк инициализируется синхронно. Все запрошенные интерфейсы доступны при возврате IDBAsynchStaus::GetStatus или ISSAsynchStatus::WaitForAsynchCompletion с указанием завершения асинхронной операции. Это не обязательно означает, что набор строк полностью заполнен, но он является полным и полностью функциональным.
Если выполненная команда не возвращает набор строк, он по-прежнему возвращается немедленно с объектом, поддерживающим IDBAsynchStatus.
Если необходимо получить несколько результатов из асинхронного выполнения команд, необходимо:
Задайте DBPROPVAL_ASYNCH_INITIALIZE бит свойства DBPROP_ROWSET_ASYNCH перед выполнением команды.
Вызовите ICommand::Execute и запросите IMultipleResults.
Затем интерфейсы IDBAsynchStatus и ISSAsynchStatus можно получить путем запроса к интерфейсу нескольких результатов с помощью QueryInterface.
После завершения выполнения команды IMultipleResults можно использовать как обычное, за исключением синхронного дела: DB_S_ASYNCHRONOUS может быть возвращено, в этом случае можно использовать IDBAsynchStatus или ISSAsynchStatus , чтобы определить, когда операция завершена.
Примеры
В следующем примере приложение вызывает неблокирующий метод, выполняет некоторую другую обработку, а затем возвращается для обработки результатов. ISSAsynchStatus::WaitForAsynchCompletion ожидает внутреннего объекта события до тех пор, пока не будет выполнена асинхронная операция выполнения или время, указанное 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 ожидает внутреннего объекта события до завершения асинхронной операции или значения dwMilisecTimeOut .
В следующем примере показана асинхронная обработка с несколькими результирующих наборами:
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();
}
}
Чтобы предотвратить блокировку, клиент может проверить состояние запущенной асинхронной операции, как показано в следующем примере:
// 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();
}
В следующем примере показано, как отменить текущую асинхронную операцию:
// 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);
}
См. также
Компоненты собственного клиента SQL Server
Свойства и поведение наборов строк
ISSAsynchStatus (OLE DB)