TN064: model wątkowości typu apartment w kontrolkach ActiveXTN064: Apartment-Model Threading in ActiveX Controls

Uwaga

Następująca Uwaga techniczna nie została zaktualizowana, ponieważ została najpierw uwzględniona w dokumentacji online.The following technical note has not been updated since it was first included in the online documentation. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe.As a result, some procedures and topics might be out of date or incorrect. Aby uzyskać najnowsze informacje, zalecamy wyszukiwanie tematu zainteresowania w indeksie dokumentacji online.For the latest information, it is recommended that you search for the topic of interest in the online documentation index.

Ta Uwaga techniczna wyjaśnia, jak włączyć wątkowość modelu Apartment w formancie ActiveX.This technical note explains how to enable apartment-model threading in an ActiveX control. Należy zauważyć, że wątkowość modelu Apartment jest obsługiwana tylko w Visual C++ w wersji 4,2 lub nowszej.Note that apartment-model threading is only supported in Visual C++ versions 4.2 or later.

Co to jest Apartment-Model wątkowośćWhat Is Apartment-Model Threading

Model apartamentu to podejście do obsługi osadzonych obiektów, takich jak kontrolki ActiveX, w ramach aplikacji kontenera wielowątkowego.The apartment model is an approach to supporting embedded objects, such as ActiveX controls, within a multithreaded container application. Mimo że aplikacja może mieć wiele wątków, każde wystąpienie osadzonego obiektu zostanie przypisane do jednej "Apartament", który będzie wykonywany tylko w jednym wątku.Although the application may have multiple threads, each instance of an embedded object will be assigned to one "apartment," which will execute on only one thread. Innymi słowy, wszystkie wywołania do wystąpienia kontrolki będą miały miejsce w tym samym wątku.In other words, all calls into an instance of a control will happen on the same thread.

Jednak różne wystąpienia tego samego typu kontrolki mogą być przypisane do różnych apartamentach.However, different instances of the same type of control may be assigned to different apartments. Tak więc, jeśli wiele wystąpień formantu współużytkuje dowolne dane (na przykład dane statyczne lub globalne), dostęp do tych udostępnionych danych będzie musiał być chroniony przez obiekt synchronizacji, taki jak Sekcja krytyczna.So, if multiple instances of a control share any data in common (for example, static or global data), then access to this shared data will need to be protected by a synchronization object, such as a critical section.

Aby uzyskać szczegółowe informacje na temat modelu wątkowego Apartment, zobacz procesy i wątki w odwołaniu OLE programisty.For complete details on the apartment threading model, please see Processes and Threads in the OLE Programmer's Reference.

Dlaczego warto obsługiwać wątki Apartment-ModelWhy Support Apartment-Model Threading

Kontrolki obsługujące wątkowość modelu Apartment mogą być używane w aplikacjach kontenera wielowątkowego, które obsługują również model Apartment.Controls that support apartment-model threading can be used in multithreaded container applications that also support the apartment model. Jeśli nie włączysz wątkowości modelu apartamentu, będzie można ograniczyć potencjalny zestaw kontenerów, w których może być używany formant.If you do not enable apartment-model threading, you will limit the potential set of containers in which your control could be used.

Włączenie wątkowości modelu Apartment jest łatwe w przypadku większości kontrolek, szczególnie w przypadku, gdy nie mają one danych udostępnionych.Enabling apartment-model threading is easy for most controls, particularly if they have little or no shared data.

Ochrona udostępnionych danychProtecting Shared Data

Jeśli kontrolka używa danych udostępnionych, takich jak statyczna zmienna członkowska, dostęp do tych danych powinien być chroniony za pomocą sekcji krytycznej, aby zapobiec modyfikowaniu danych w tym samym czasie przez więcej niż jeden wątek.If your control uses shared data, such as a static member variable, access to that data should be protected with a critical section to prevent more than one thread from modifying the data at the same time. Aby skonfigurować sekcję krytyczną dla tego celu, zadeklaruj statyczną zmienną składową klasy CCriticalSection w klasie formantu.To set up a critical section for this purpose, declare a static member variable of class CCriticalSection in your control's class. Użyj Lock funkcji i Unlock elementu członkowskiego tego obiektu sekcji krytycznej wszędzie tam, gdzie kod uzyskuje dostęp do udostępnionych danych.Use the Lock and Unlock member functions of this critical section object wherever your code accesses the shared data.

Rozważmy na przykład klasę kontrolki, która musi obsługiwać ciąg, który jest współużytkowany przez wszystkie wystąpienia.Consider, for example, a control class that needs to maintain a string that is shared by all instances. Ten ciąg może być obsługiwany w statycznej zmiennej składowej i chroniony przez sekcję krytyczną.This string can be maintained in a static member variable and protected by a critical section. Deklaracja klasy kontrolki będzie zawierać następujące elementy:The control's class declaration would contain the following:

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

Implementacja klasy obejmuje definicje dla następujących zmiennych:The implementation for the class would include definitions for these variables:

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

Dostęp do _strShared statycznego elementu członkowskiego może następnie być chroniony przez sekcję krytyczną:Access to the _strShared static member can then be protected by the critical section:

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

...
}

Rejestrowanie kontrolki obsługującej model typu ApartmentRegistering an Apartment-Model-Aware Control

Kontrolki obsługujące wątkowość modelu Apartment powinny wskazywać tę możliwość w rejestrze, dodając nazwaną wartość "ThreadingModel" z wartością "Apartment" w wpisie rejestru identyfikatora klasy w obszarze Identyfikator klasy \ InprocServer32 klucza.Controls that support apartment-model threading should indicate this capability in the registry, by adding the named value "ThreadingModel" with a value of "Apartment" in their class ID registry entry under the class id\InprocServer32 key. Aby spowodować automatyczne zarejestrowanie tego klucza dla formantu, należy przekazać flagę afxRegApartmentThreading w szóstym parametrze do AfxOleRegisterControlClass :To cause this key to be automatically registered for your control, pass the afxRegApartmentThreading flag in the sixth parameter to 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);

}

Jeśli projekt kontrolki został wygenerowany przez ControlWizard w Visual C++ w wersji 4,1 lub nowszej, ta flaga będzie już obecna w kodzie.If your control project was generated by ControlWizard in Visual C++ version 4.1 or later, this flag will already be present in your code. Nie są wymagane żadne zmiany, aby zarejestrować model wątkowości.No changes are necessary to register the threading model.

Jeśli projekt został wygenerowany przez wcześniejszą wersję programu ControlWizard, istniejący kod będzie miał wartość logiczną jako szósty parametr.If your project was generated by an earlier version of ControlWizard, your existing code will have a Boolean value as the sixth parameter. Jeśli istniejący parametr ma wartość TRUE, zmień go na afxRegInsertable | afxRegApartmentThreading.If the existing parameter is TRUE, change it to afxRegInsertable | afxRegApartmentThreading. Jeśli istniejący parametr ma wartość FALSE, zmień go na afxRegApartmentThreading.If the existing parameter is FALSE, change it to afxRegApartmentThreading.

Jeśli formant nie jest zgodny z regułami dla wątków modelu Apartment, nie należy przekazywać afxRegApartmentThreading w tym parametrze.If your control does not follow the rules for apartment-model threading, you must not pass afxRegApartmentThreading in this parameter.

Zobacz teżSee also

Uwagi techniczne według numeruTechnical Notes by Number
Uwagi techniczne według kategoriiTechnical Notes by Category