TN064 : Appartement-modèle de Threading dans les contrôles ActiveX

Cette note technique explique comment activer appartement-modèle threading dans un contrôle ActiveX. Notez qu'appartement-modèle de filetage est supporté uniquement dans les versions de Visual C++ 4.2 ou ultérieures.

Ce qui est d'appartement-modèle de filetage?

Le modèle de l'appartement est une approche de soutien des objets incorporés, tels que les contrôles ActiveX dans une application multithread conteneur. Bien que l'application peut avoir plusieurs threads, chaque instance d'un objet incorporé sera affecté à un « appartement » qui s'exécutent sur un seul thread. En d'autres termes, tous les appels vers une instance d'un contrôle se passera sur le même thread.

Cependant, différentes instances du même type de contrôle peuvent être affectés aux différents appartements. Ainsi, si plusieurs instances d'un contrôle de partagent toutes les données en commun (par exemple, les données statiques ou globales), puis accès aux données partagées, aura besoin d'être protégés par un objet de synchronisation, comme une section critique.

Pour plus de détails sur l'appartement de modèle de thread, consultez processus et des Threads dans le OLE de référence du programmeur.

Pourquoi soutenir appartement-modèle de filetage?

Contrôles prenant en charge appartement-modèle de filetage peuvent être utilisés dans les applications multithread contenant également en charge le modèle de l'appartement. Si vous n'activez pas appartement-modèle de filetage, vous limiterez l'ensemble potentiel de contenants dans lesquels on pourrait servir votre contrôle.

Activation d'appartement-modèle de filetage est facile pour la plupart des contrôles, surtout si elles ont peu ou pas de données partagées.

Protection des données partagées

Si votre contrôle utilise des données partagées, comme une variable de membre statique, accès pour que les données doivent être protégées avec une section critique pour empêcher la modification des données en même temps plus d'un thread. De mettre en place une section critique à cette fin, déclarez une variable de membre statique de classe CCriticalSection dans la classe de votre contrôle. Utilisez les fonctions Lock et Unlock membres de cet objet section critique où votre code accède à des données partagées.

Considérons, par exemple, une classe de contrôle qui doit maintenir une chaîne qui est partagée par toutes les instances. Cette chaîne peut être maintenue dans une variable de membre statique et protégée par une section critique. Déclaration de la classe du contrôle contiendrait les éléments suivants:

class CSampleCtrl : public COleCo&ntrol
{
 nbsp ;  ...
    statique CString _strShared ;
    statique CCriticalSection _critSect ;
}

La mise en œuvre de la classe comprendrait les définitions pour ces variables:

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

L'accès à le _strShared membre statique peut ensuite être protégée par la section critique:

vOID CSampleCtrl::SomeMethod()
{
 nbsp ;  _critSect.Lock() ;
    Si (_strShared.Empty())
        _strShared = « <text> » ;
    _critSect.unlock() ;
    ...
}

Enregistrement d'un contrôle conscient-appartement-modèle

Contrôles prenant en charge appartement-modèle de filetage doivent indiquer cette capacité dans le registre, en ajoutant la valeur nommée « ThreadingModel » d'une valeur de « Appartement » dans leur entrée de Registre ID classe sous l' id de classe\ cléInprocServer32 . À cause de cette clé être automatiquement inscrit pour votre contrôle, passer la afxRegApartmentThreading drapeau dans le sixième paramètre à AfxOleRegisterControlClass:

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

Si votre projet de contrôle a été généré par ControlWizard en version 4.1 ou une version ultérieure de Visual C++, cet indicateur sera déjà présent dans votre code. Aucun changement n'est nécessaires pour enregistrer le modèle de thread.

Si votre projet a été généré par une version antérieure de ControlWizard, votre code existant aura une valeur booléenne comme sixième paramètre. Si le paramètre existant est TRUE, changer à afxRegInsertable | afxRegApartmentThreading . Si le paramètre existant est FALSE, changer de afxRegApartmentThreading.

Si votre contrôle ne suit pas les règles d'appartement-modèle de filetage, vous ne devez pas passer afxRegApartmentThreading dans ce paramètre.

&Notes techniques par le numéro |nbsp ; Notes techniques par catégorie

Index