Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Sistema de Plataforma de Análise (PDW)
Base de dados SQL no Microsoft Fabric
O SQL Server permite que as aplicações realizem operações assíncronas em bases de dados. O processamento assíncrono permite que os métodos retornem imediatamente sem serem bloqueados no thread que chama. Isto permite grande parte da potência e flexibilidade do multithreading, sem exigir que o programador crie explicitamente threads ou trate da sincronização. As aplicações solicitam processamento assíncrono ao inicializar uma ligação a uma base de dados ou ao inicializar o resultado da execução de um comando.
Abrir e Fechar uma Ligação à Base de Dados
Ao utilizar o OLE DB Driver para SQL Server, aplicações concebidas para inicializar um objeto 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 esta propriedade é definida, o fornecedor 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 assíncrona. As aplicações podem consultar a interface IDBAsynchStatus ou ISSAsynchStatus no objeto fonte de dados e depois chamar IDBAsynchStatus::GetStatus ou ISSAsynchStatus::WaitForAsynchCompletion para obter o estado da inicialização.
Além disso, a propriedade SSPROP_ISSAsynchStatus foi adicionada ao conjunto de propriedades DBPROPSET_SQLSERVERROWSET. Os fornecedores que suportam a interface ISSAsynchStatus devem implementar esta propriedade com um valor de VARIANT_TRUE.
IDBAsynchStatus::Abort ou ISSAsynchStatus::Abort podem ser chamados para cancelar a chamada Initialize assíncrona. O consumidor deve solicitar explicitamente a Inicialização da Fonte de Dados Assíncrona. Caso contrário, IDBInitialize::Initialize não retorna até que o objeto fonte de dados esteja completamente inicializado.
Observação
Os objetos fonte de dados usados para pooling de ligações não podem chamar a interface ISSAsynchStatus no Driver OLE DB para SQL Server. A interface ISSAsynchStatus não está exposta para objetos de fonte de dados agrupados.
Se uma aplicação forçar explicitamente a utilização do motor de cursores, IOpenRowset::OpenRowset e IMultipleResults::GetResult não suportarão processamento assíncrono.
Além disso, o proxy remoto/dll de stub (no MDAC 2.8) não pode chamar a interface ISSAsynchStatus no OLE DB Driver para SQL Server. A interface ISSAsynchStatus não é exposta através do remoto.
Os Componentes de Serviço não suportam ISSAsynchStatus.
Execução e inicialização de conjuntos de linhas
Aplicações concebidas para abrir assíncronamente o resultado da execução de um comando podem definir o bit DBPROPVAL_ASYNCH_INITIALIZE na propriedade DBPROP_ROWSET_ASYNCH. Ao definir este 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 a inicializar assíncronamente, com o ppRowset definido para a interface solicitada no conjunto de linhas. Para o Driver OLE DB para SQL Server, esta interface só pode ser IDBAsynchStatus ou ISSAsynchStatus. Até que o conjunto de linhas esteja totalmente inicializado, esta interface comporta-se como se estivesse num estado suspenso, e chamar QueryInterface para interfaces que não sejam IID_IDBAsynchStatus ou IID_ISSAsynchStatus pode devolver E_NOINTERFACE. A menos que o consumidor solicite explicitamente processamento assíncrono, o conjunto de linhas é inicializado de forma síncrona. Todas as interfaces solicitadas estão disponíveis quando IDBAsynchStatus::GetStatus ou ISSAsynchStatus::WaitForAsynchCompletion regressam com a indicação de que a operação assíncrona está concluída. Isto não significa necessariamente que o conjunto de linhas esteja totalmente preenchido, mas sim completo e totalmente funcional.
Se o comando executado não devolver um conjunto de linhas, ele devolve imediatamente um objeto que suporta IDBAsynchStatus.
Se precisar de obter múltiplos resultados da execução assíncrona de comandos, deve:
Defina o bit DBPROPVAL_ASYNCH_INITIALIZE da propriedade DBPROP_ROWSET_ASYNCH antes de executar o comando.
Ligue para o ICommand::Execute e solicite IMultipleResults.
As interfaces IDBAsynchStatus e ISSAsynchStatus podem então ser obtidas consultando a interface de múltiplos resultados usando o QueryInterface.
Quando o comando termina de ser executado, o IMultipleResults pode ser usado normalmente, com uma exceção do caso síncrono: DB_S_ASYNCHRONOUS pode ser devolvido, caso em que IDBAsynchStatus ou ISSAsynchStatus podem ser usados para determinar quando a operação está completa.
Examples
No exemplo seguinte, a aplicação chama um método não bloqueante, faz algum outro processamento e depois regressa para processar os resultados. ISSAsynchStatus::WaitForAsynchCompletion espera no objeto de evento interno até que a operação em execução assíncrona seja concluída ou até que o tempo especificado por 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 espera pelo 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 seguinte mostra processamento assíncrono com múltiplos 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 bloqueios, o cliente pode verificar o estado de uma operação assíncrona em execução, como no seguinte exemplo:
// 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 seguinte demonstra como pode cancelar a operação assíncrona atualmente em execução:
// 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);
}
Ver também
Driver OLE DB para Funcionalidades do SQL Server
Propriedades e Comportamentos do Conjunto de Linhas
ISSAsynchStatus (OLE DB)