Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O SQL Server permite que os aplicativos executem operações de banco de dados assíncronas. O processamento assíncrono permite que os métodos retornem imediatamente sem bloquear o thread de chamada. Isso permite grande parte do poder e flexibilidade do multithreading, sem exigir que o desenvolvedor crie explicitamente threads ou manipule a sincronização. Os aplicativos solicitam processamento assíncrono ao inicializar uma conexão de banco de dados ou ao inicializar o resultado da execução de um comando.
Abrir e fechar uma conexão de banco de dados
Ao usar o provedor OLE DB do SQL Server Native Client, os aplicativos projetados para inicializar um objeto de fonte de dados de forma assíncrona podem definir o bit DBPROPVAL_ASYNCH_INITIALIZE na propriedade DBPROP_INIT_ASYNCH antes de chamar IDBInitialize::Initialize. Quando essa propriedade é definida, o provedor retorna imediatamente da chamada para Inicializar com S_OK, se a operação tiver sido concluída imediatamente ou DB_S_ASYNCHRONOUS, se a inicialização continuar de forma assíncrona. Os aplicativos podem consultar a interface IDBAsynchStatus ou ISSAsynchStatusno objeto de fonte de dados e chamar IDBAsynchStatus::GetStatus ouISSAsynchStatus::WaitForAsynchCompletion para obter o status da inicialização.
Além disso, a propriedade SSPROP_ISSAsynchStatus foi adicionada ao conjunto de propriedades DBPROPSET_SQLSERVERROWSET. Os provedores que dão suporte à interface ISSAsynchStatus devem implementar essa propriedade com um valor de VARIANT_TRUE.
IDBAsynchStatus::Abort ou ISSAsynchStatus::Abort pode ser chamado para cancelar a chamada de inicialização assíncrona. O consumidor deve solicitar explicitamente a inicialização assíncrona da fonte de dados. Caso contrário, IDBInitialize::Initialize não retornará até que o objeto da fonte de dados seja completamente inicializado.
Observação
Os objetos de fonte de dados usados para o pool de conexões não podem chamar a interface ISSAsynchStatus no provedor OLE DB do SQL Server Native Client. A interface ISSAsynchStatus não é exposta para objetos de fonte de dados em pool.
Se um aplicativo força explicitamente o uso do mecanismo de cursor, IOpenRowset::OpenRowset e IMultipleResults::GetResult não oferecerão suporte ao processamento assíncrono.
Além disso, o proxy/stub dll de comunicação remota (no MDAC 2.8) não pode chamar a interface ISSAsynchStatus no SQL Server Native Client. A interface ISSAsynchStatus não é exposta por meio da comunicação remota.
Os Componentes de Serviço não dão suporte a ISSAsynchStatus.
Inicialização de execução e conjunto de linhas
Aplicativos projetados para abrir de forma assíncrona o resultado da execução de um comando podem definir o bit DBPROPVAL_ASYNCH_INITIALIZE na propriedade DBPROP_ROWSET_ASYNCH. Ao definir esse bit antes de chamar IDBInitialize::Initialize, ICommand::Execute, IOpenRowset::OpenRowset ou IMultipleResults::GetResult, o argumento riid deve ser definido como IID_IDBAsynchStatus, IID_ISSAsynchStatus ou IID_IUnknown.
O método retorna imediatamente com S_OK se a inicialização do conjunto de linhas for concluída imediatamente ou com DB_S_ASYNCHRONOUS se o conjunto de linhas continuar inicializando de forma assíncrona, com ppRowset definido como a interface solicitada no conjunto de linhas. Para o provedor OLE DB do SQL Server Native Client, essa interface só pode ser IDBAsynchStatus ou ISSAsynchStatus. Até que o conjunto de linhas seja totalmente inicializado, essa interface se comporta como se estivesse em um estado suspenso e chamar QueryInterface para interfaces diferentes de IID_IDBAsynchStatus ou IID_ISSAsynchStatus pode retornar E_NOINTERFACE. A menos que o consumidor solicite explicitamente o processamento assíncrono, o conjunto de linhas é inicializado de forma síncrona. Todas as interfaces solicitadas estão disponíveis quando IDBAsynchStaus::GetStatus ou ISSAsynchStatus::WaitForAsynchCompletion retorna com a indicação de que a operação assíncrona está concluída. Isso não significa necessariamente que o conjunto de linhas está totalmente preenchido, mas é completo e totalmente funcional.
Se o comando executado não retornar um conjunto de linhas, ele ainda retornará imediatamente com um objeto que dá suporte a IDBAsynchStatus.
Se você precisar obter vários resultados da execução de comando assíncrono, deverá:
Defina o bit DBPROPVAL_ASYNCH_INITIALIZE da propriedade DBPROP_ROWSET_ASYNCH antes de executar o comando.
Chame ICommand::Execute e solicite IMultipleResults.
As interfaces IDBAsynchStatus e ISSAsynchStatus podem ser obtidas consultando a interface de vários resultados usando QueryInterface.
Quando o comando terminar de ser executado, IMultipleResults poderá ser usado normalmente, com uma exceção do caso síncrono: DB_S_ASYNCHRONOUS podem ser retornados; nesse caso, IDBAsynchStatus ou ISSAsynchStatus pode ser usado para determinar quando a operação é concluída.
Exemplos
No exemplo a seguir, o aplicativo chama um método de não bloqueio, faz algum outro processamento e retorna para processar os resultados. ISSAsynchStatus::WaitForAsynchCompletion aguarda o objeto de evento interno até que a operação de execução assíncrona seja concluída ou o tempo especificado pelo dwMilisecTimeOut seja passado.
// 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 aguarda o objeto de evento interno até que a operação de execução assíncrona seja concluída ou o valor dwMilisecTimeOut seja passado.
O exemplo a seguir mostra o processamento assíncrono com vários conjuntos de resultados:
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();
}
}
Para evitar o bloqueio, o cliente pode verificar o status de uma operação assíncrona em execução, como no exemplo a seguir:
// 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();
}
O exemplo a seguir demonstra como você pode cancelar a operação assíncrona em execução no momento:
// 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);
}
Consulte Também
Recursos do SQL Server Native Client
Propriedades e comportamentos do conjunto de linhas
ISSAsynchStatus (OLE DB)