TN064: Compartimento-modelo Threading nos controles ActiveX

ObservaçãoObservação

A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.As informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação on-line.

Esta nota técnica explica como habilitar o modelo apartment threading em um controle ActiveX.Observe que somente modelo apartment threading é suportado nas versões do Visual C++ 4.2 ou posteriores.

O que é o modelo Apartment Threading?

O modelo de apartment é uma abordagem para oferecer suporte a objetos incorporados, como controles de ActiveX, dentro de um aplicativo de contêiner multithread.Embora o aplicativo pode ter vários segmentos, cada instância de um objeto incorporado será atribuída a um "apartment," que irá executar em apenas um segmento.Em outras palavras, todas as chamadas para uma instância de um controle acontecerá no mesmo thread.

Entretanto, instâncias diferentes do mesmo tipo de controle podem ser atribuídas a apartments diferentes.Portanto, se várias instâncias de um controle de compartilharem dados em comum (por exemplo, dados estáticos ou globais), acesso a dados compartilhados precisará ser protegido por um objeto de sincronização, como uma seção crítica.

Para obter detalhes completos sobre o modelo apartment threading, consulte processos e Threads na OLE Programmer referência.

Por que suporta modelo Apartment Threading?

Controles que suportam o modelo apartment threading podem ser usados em aplicativos multithread do recipiente que também suportam o modelo de apartment.Se você não habilitar o modelo apartment threading, limitará o conjunto potencial de contêineres no qual o controle pode ser usado.

Ativar modelo apartment threading é fácil para a maioria dos controles, especialmente se eles têm pouca ou nenhuma dados compartilhados.

Protegendo dados compartilhados

Se o seu controle usa dados compartilhados, como uma variável de membro estático, acesso para que os dados devem ser protegidos com uma seção crítica para impedir que mais de um segmento de modificação de dados ao mesmo tempo.Para configurar uma seção crítica para essa finalidade, declare uma variável de membro estático da classe CCriticalSection na classe do controle.Use o Lock e Desbloquear funções de membro desta seção crítica do objeto sempre que seu código acessa os dados compartilhados.

Considere, por exemplo, uma classe de controle precisa manter uma seqüência de caracteres que é compartilhada por todas as instâncias.Essa seqüência pode ser mantida em uma variável de membro estático e protegida por uma seção crítica.Declaração de classe do controle deve conter o seguinte:

class CSampleCtrl : public COleControl
{
    ...
    static CString _strShared;
    static CCriticalSection _critSect;
};

A implementação da classe incluiria definições para essas variáveis:

int CString CSampleCtrl::_strShared;
CCriticalSection CSampleCtrl::_critSect;

Acesso a _strShared membro estático então pode ser protegido pela seção crítica:

void CSampleCtrl::SomeMethod()
{
    _critSect.Lock();
    if (_strShared.Empty())
        _strShared = "<text>";
    _critSect.Unlock();
    ...
}

Registrar um controle ciente de modelo Apartment

Controles que suportam o modelo apartment threading devem indicar esse recurso no registro, adicionando o valor nomeado "ThreadingModel" com um valor de "Apartment" na entrada de registro de ID de classe sob o id de classe\InprocServer32 chave.Para fazer com que essa chave seja registrado automaticamente para seu controle, passar o afxRegApartmentThreading sinalizador no sexto parâmetro para AfxOleRegisterControlClass:

BOOL CSampleCtrl::CSampleCtrlFactory::UpdateRegistry(BOOL bRegister)
{
    if (bRegister)
        return AfxOleRegisterControlClass(
            AfxGetInstanceHandle(),
            m_clsid,
            m_lpszProgID,
            IDS_SAMPLE,
            IDB_SAMPLE,
            afxRegApartmentThreading,
            _dwSampleOleMisc,
            _tlid,
            _wVerMajor,
            _wVerMinor);
    else
        return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}

Se seu projeto de controle foi gerado pelo WebAssistente no Visual C++ versão 4.1 ou posterior, este sinalizador já estarão presente no seu código.Não são necessárias alterações para registrar o modelo de threading.

Se o projeto foi gerado por uma versão anterior do WebAssistente, seu código existente terá um valor booleano como o sexto parâmetro.Se o parâmetro existente for TRUE, altere-a para afxRegInsertable | afxRegApartmentThreading.Se o parâmetro existente for FALSE, altere-a para afxRegApartmentThreading.

Se o controle não segue as regras de modelo apartment threading, você não deve passar afxRegApartmentThreading neste parâmetro.

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria