TN064 : Threads de modèle cloisonné dans les contrôles ActiveX
[!REMARQUE]
La note technique suivante n'a pas été modifiée depuis si c'était première inclus dans la documentation en ligne.Par conséquent, certaines procédures et rubriques peuvent être obsolètes ou incorrects.Pour obtenir les informations les plus récentes, il est recommandé que vous trouviez la rubrique d'intérêt dans l'index de la documentation en ligne.
Cette note technique explique comment activer le threading de modèle appartement dans un contrôle ActiveX.Notez que les threads de modèle appartement est uniquement disponible dans les versions de Visual C++ 4,2 ou version ultérieure.
Quel est threading de modèle appartement ?
Le modèle de cloisonnement est une approche pour prendre en charge les objets incorporés, tels que les contrôles ActiveX, dans une application conteneur multithread.Bien que l'application puisse avoir plusieurs threads, chaque instance d'un objet incorporé sera assignée à un « apartment », qui s'exécutera sur un seul thread.En d'autres termes, tous les appels dans une instance d'un contrôle se produiront sur le même thread.
Toutefois, plusieurs instances du même type de contrôle peuvent être assignées à des apartments.Ainsi, si plusieurs instances d'un partage de contrôle gère les données en commun (par exemple, les données statiques ou globales), accèdent ensuite à faire des données partagées doivent être protégées par un objet de synchronisation, tel qu'une section critique.
Pour plus de détails sur le thread cloisonné consultez Threads et processus dans la notion de référence du programmeur.
Pourquoi prennent en charge le threading de modèle appartement ?
Les contrôles qui prennent en charge les threads de modèle appartement peuvent être utilisés dans des applications multithread conteneur qui prennent également en charge le modèle appartement.Si vous n'activez pas le threading de modèle cloisonné, vous limiterez il est défini des conteneurs dans lesquels votre contrôle peut être utilisé.
Activer le threading de modèle appartement est facile pour la plupart des contrôles, en particulier s'ils 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, telles qu'une variable membre statique, l'accès à ces données doivent être protégées avec une section critique pour empêcher plusieurs threads de modifier les données en même temps.Pour installer une section critique à cet effet, déclarez une variable membre statique de classe CCriticalSection dans la classe de votre contrôle.Utilisez les fonctions membres d' Lock et de Déverrouiller de cet objet de section critique partout où votre code accède aux données partagées.
Considérons, par exemple, une classe de contrôle qui doit stocker une chaîne qui est partagée par toutes les instances.Cette chaîne peut être conservée dans une variable membre statique et être protégée par une section critique.La déclaration de classe du contrôle contiendrait les éléments suivants :
class CSampleCtrl : public COleControl
{
...
static CString _strShared;
static CCriticalSection _critSect;
};
L'implémentation de la classe inclut les définitions de ces variables :
int CString CSampleCtrl::_strShared;
CCriticalSection CSampleCtrl::_critSect;
Accès au membre statique d' _strShared peut ensuite être protégé par la section critique :
void CSampleCtrl::SomeMethod()
{
_critSect.Lock();
if (_strShared.Empty())
_strShared = "<text>";
_critSect.Unlock();
...
}
Enregistrer un contrôle Apartment-Modèle-Averti
Les contrôles qui prennent en charge le threading de modèle appartement doivent indiquer cette fonction dans le Registre, en ajoutant la valeur nommée « ThreadingModel » avec la valeur « apartment » dans leur entrée du Registre d'ID de classe sous l'identificateur de classe\ clé d'InprocServer32 .Pour que cette clé à enregistrer automatiquement pour votre contrôle, passez la balise d' afxRegApartmentThreading du sixième paramètre à 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);
}
Si votre projet de contrôle a été généré par ControlWizard dans Visual C++ version 4,1 ou version ultérieure, cette balise est déjà présente dans votre code.Aucune modification n'est nécessaire pour signaler 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 VRAI, modifiez-le àafxRegInsertable | afxRegApartmentThreading.Si le paramètre existant est FAUX, modifiez-le àafxRegApartmentThreading.
Si votre contrôle ne suit pas les règles du threading de modèle cloisonné, vous n'avez pas besoin de passer afxRegApartmentThreading dans ce paramètre.