İş Parçacığı Oluşturma ve Hazırlama (C++/CX)
Çoğu durumda, standart C++ nesneleri gibi Windows Çalışma Zamanı sınıf örneklerine herhangi bir iş parçacığından erişilebilir. Bu tür sınıflar "çevik" olarak adlandırılır. Ancak, Windows ile birlikte gelen az sayıda Windows Çalışma Zamanı sınıfı çevik değildir ve standart C++ nesnelerine kıyasla COM nesneleri gibi kullanılmalıdır. Çevik olmayan sınıfları kullanmak için COM uzmanı olmanız gerekmez, ancak sınıfın iş parçacığı modelini ve sıralama davranışını dikkate almanız gerekir. Bu makale, çevik olmayan bir sınıfın örneğini kullanmanız gereken nadir senaryolar için arka plan ve rehberlik sağlar.
İş parçacığı modeli ve hazırlama davranışı
Windows Çalışma Zamanı sınıfı, eş zamanlı iş parçacığı erişimini, ona uygulanan iki öznitelik tarafından gösterildiği gibi çeşitli şekillerde destekleyebilir:
ThreadingModel
özniteliği, sabit listesi tarafındanThreadingModel
tanımlandığı gibi STA, MTA veya Both değerlerinden birine sahip olabilir.MarshallingBehavior
özniteliği, sabit listesi tarafındanMarshallingType
tanımlanan Çevik, Yok veya Standart değerlerinden birine sahip olabilir.
ThreadingModel
özniteliği, sınıfın etkinleştirildiğinde yüklendiği yeri belirtir: yalnızca kullanıcı arabirimi iş parçacığı (STA) bağlamında, yalnızca arka plan iş parçacığı (MTA) bağlamında veya nesneyi oluşturan iş parçacığı bağlamında (Her İkisi). MarshallingBehavior
Öznitelik değerleri, nesnenin çeşitli iş parçacığı bağlamlarında nasıl davrandığını ifade eder; çoğu durumda, bu değerleri ayrıntılı olarak anlamanız gerekmez. Windows API'si tarafından sağlanan sınıfların yaklaşık yüzde 90'ının =Her İkisi ve MarshallingType
=Çevik değeri vardırThreadingModel
. Bu, alt düzey iş parçacığı ayrıntılarını saydam ve verimli bir şekilde işleyebileceği anlamına gelir. Bir "çevik" sınıf oluşturmak için kullandığınızda ref new
, bu sınıf üzerindeki yöntemleri ana uygulama iş parçacığınızdan veya bir veya daha fazla çalışan iş parçacığından çağırabilirsiniz. Başka bir deyişle, kodunuzda herhangi bir yerden Windows veya üçüncü taraf tarafından sağlanmış olsa da çevik bir sınıf kullanabilirsiniz. Sınıfın iş parçacığı modeli veya sıralama davranışıyla ilgilenmeniz gerekmez.
Windows Çalışma Zamanı bileşenlerini kullanma
bir Evrensel Windows Platformu uygulaması oluşturduğunuzda hem çevik hem de çevik olmayan bileşenlerle etkileşim kurabilirsiniz. Çevik olmayan bileşenlerle etkileşim kurarken aşağıdaki uyarıyla karşılaşabilirsiniz.
Çevik olmayan sınıflar tüketirken derleyici uyarısı C4451
Çeşitli nedenlerle bazı sınıflar çevik olamaz. Hem kullanıcı arabirimi iş parçacığından hem de arka plan iş parçacığından çevik olmayan sınıfların örneklerine erişiyorsanız, çalışma zamanında doğru davranışı sağlamak için ek dikkat edin. Microsoft C++ derleyicisi, uygulamanızda genel kapsamda çevik olmayan bir çalışma zamanı sınıfı örneği oluşturduğunuzda veya çevik olmayan bir türü çevik olarak işaretlenen bir başvuru sınıfında sınıf üyesi olarak bildirdiğinizde uyarılarda bulunur.
Çevik olmayan sınıflardan en kolayı = Hem hem de MarshallingType
=Standart olanlardırThreadingModel
. Yalnızca yardımcı sınıfını kullanarak Agile<T>
bu sınıfları çevik hale getirebilirsiniz. Aşağıdaki örnek, türünde Windows::Security::Credentials::UI::CredentialPickerOptions^
çevik olmayan bir nesnenin bildirimini ve sonuç olarak verilen derleyici uyarısını gösterir.
ref class MyOptions
{
public:
property Windows::Security::Credentials::UI::CredentialPickerOptions^ Options
{
Windows::Security::Credentials::UI::CredentialPickerOptions^ get()
{
return _myOptions;
}
}
private:
Windows::Security::Credentials::UI::CredentialPickerOptions^ _myOptions;
};
İşte verilen uyarı:
Warning 1 warning C4451: 'Platform::Agile<T>::_object' : Usage of ref class 'Windows::Security::Credentials::UI::CredentialPickerOptions' inside this context can lead to invalid marshaling of object across contexts. Consider using 'Platform::Agile<Windows::Security::Credentials::UI::CredentialPickerOptions>' instead
"Standart" sıralama davranışına sahip bir nesneye üye kapsamında veya genel kapsamda bir başvuru eklediğinizde, derleyici türü Platform::Agile<T>
içinde sarmalamanızı öneren bir uyarı döndürür: Consider using 'Platform::Agile<Windows::Security::Credentials::UI::CredentialPickerOptions>' instead
kullanıyorsanız Agile<T>
, sınıfı diğer çevik sınıflar gibi kullanabilirsiniz. Şu durumlarda kullanın Platform::Agile<T>
:
Çevik olmayan değişken genel kapsamda bildirilir.
Çevik olmayan değişken sınıf kapsamında bildirilir ve kod kullanmanın işaretçiyi kaçırma olasılığı vardır; başka bir deyişle, doğru sıralama olmadan bunu farklı bir dairede kullanın.
Bu koşullardan hiçbiri geçerli değilse, içeren sınıfı çevik olmayan olarak işaretleyebilirsiniz. Başka bir deyişle, çevik olmayan nesneleri yalnızca çevik olmayan sınıflarda doğrudan tutmanız ve çevik sınıflarda Platform::Agile<T> aracılığıyla çevik olmayan nesneleri tutmanız gerekir.
Aşağıdaki örnekte, uyarıyı güvenle yoksayabilmek için nasıl kullanılacağı Agile<T>
gösterilmektedir.
#include <agile.h>
ref class MyOptions
{
public:
property Windows::Security::Credentials::UI::CredentialPickerOptions^ Options
{
Windows::Security::Credentials::UI::CredentialPickerOptions^ get()
{
return m_myOptions.Get();
}
}
private:
Platform::Agile<Windows::Security::Credentials::UI::CredentialPickerOptions^> m_myOptions;
};
Agile
Ref sınıfında dönüş değeri veya parametre olarak geçirilemediğine dikkat edin. yöntemi, Agile<T>::Get()
ortak bir yöntemde veya özellikte uygulama ikili arabirimi (ABI) üzerinden geçirebileceğiniz tanıtıcıdan nesneye (^) döndürür.
"Hiçbiri" hazırlama davranışına sahip bir proc Windows Çalışma Zamanı sınıfına başvuru oluşturduğunuzda, derleyici C4451 uyarısını döndürür, ancak kullanmayı Platform::Agile<T>
düşünmenizi önermez. Derleyici bu uyarının ötesinde herhangi bir yardım sunamaz, bu nedenle sınıfı doğru kullanmak ve kodunuzun STA bileşenlerini yalnızca kullanıcı arabirimi iş parçacığından ve MTA bileşenlerini yalnızca arka plan iş parçacığından çağırdığından emin olmak sizin sorumluluğunuzdadır.
Çevik Windows Çalışma Zamanı bileşenleri yazma
C++/CX'te bir başv sınıfı tanımladığınızda, varsayılan olarak çeviktir; yani =Her İkisi ve MarshallingType
=Çevik değerlerine sahiptirThreadingModel
. Windows Çalışma Zamanı C++ Şablon Kitaplığı kullanıyorsanız, öğesini kullanan FreeThreadedMarshaller
öğesinden FtmBase
türeterek sınıfınızı çevik hale getirebilirsiniz. =Both veya ThreadingModel
=MTA içeren ThreadingModel
bir sınıf yazarsanız, sınıfın iş parçacığı açısından güvenli olduğundan emin olun.
Bir başvuru sınıfının iş parçacığı modelini ve sıralama davranışını değiştirebilirsiniz. Ancak, sınıfı çevik olmayan bir şekilde işleyen değişiklikler yaparsanız, bu değişikliklerle ilişkili etkileri anlamanız gerekir.
Aşağıdaki örnekte, Windows Çalışma Zamanı sınıf kitaplığındaki bir çalışma zamanı sınıfına ve ThreadingModel
özniteliklerinin nasıl uygulanacağı MarshalingBehavior
gösterilmektedir. Bir uygulama DLL'yi kullandığında ve sınıf MySTAClass
nesnesini etkinleştirmek için anahtar sözcüğünü ref new
kullandığında, nesne tek iş parçacıklı bir dairede etkinleştirilir ve hazırlamayı desteklemez.
using namespace Windows::Foundation::Metadata;
using namespace Platform;
[Threading(ThreadingModel::STA)]
[MarshalingBehavior(MarshalingType::None)]
public ref class MySTAClass
{
};
Korumasız bir sınıfın, derleyicinin türetilmiş sınıfların bu öznitelikler için aynı değere sahip olduğunu doğrulayabilmesi için sıralama ve iş parçacığı öznitelik ayarlarına sahip olması gerekir. Sınıfın ayarları açıkça ayarlı değilse, derleyici bir hata oluşturur ve derlenemez. Korumasız bir sınıftan türetilen tüm sınıflar şu durumlardan birinde derleyici hatası oluşturur:
ThreadingModel
veMarshallingBehavior
öznitelikleri türetilmiş sınıfta tanımlanmaz.Türetilmiş sınıftaki ve
MarshallingBehavior
özniteliklerinin değerleriThreadingModel
temel sınıftakilerle eşleşmiyor.
Üçüncü taraf Windows Çalışma Zamanı bileşeni için gereken iş parçacığı oluşturma ve hazırlama bilgileri, bileşenin uygulama bildirimi kayıt bilgilerinde belirtilir. Tüm Windows Çalışma Zamanı bileşenlerinizi çevik hale getirmenizi öneririz. Bu, istemci kodunun uygulamadaki herhangi bir iş parçacığından bileşeninizi çağırabilmesini sağlar ve hazırlaması olmayan doğrudan çağrılar olduğundan bu çağrıların performansını artırır. Sınıfınızı bu şekilde yazarsanız istemci kodunun sınıfınızı kullanmak için kullanması Platform::Agile<T>
gerekmez.