Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ve většině případů je instance třídy prostředí Windows Runtime přístupná z libovolného vlákna (stejně jako většina standardních objektů C++). Taková třída prostředí Windows Runtime je agilní. Pouze malý počet tříd prostředí Windows Runtime dodávaných se systémem Windows je neagilních, ale když je používáte, musíte brát v úvahu jejich model vláknění a chování při marshalingu (marshaling je předávání dat přes hranici apartmentu). Pro každý prostředí Windows Runtime objekt je vhodné, aby byl agilní, takže vaše vlastní typy C++/WinRT jsou ve výchozím nastavení agilní.
Můžete se ale rozhodnout tuto možnost nevyužít. Můžete mít například pádný důvod vyžadovat, aby objekt vašeho typu byl umístěn v daném jednovláknovém apartmentu. Obvykle to souvisí s požadavky na reentrantnost. Ale i API uživatelského rozhraní (UI) stále častěji nabízejí agilní objekty. Obecně platí, že flexibilita je nejjednodušší a nejvýkonnější možností. Pokud implementujete aktivační továrnu, musí být agilní i v případě, že odpovídající třída modulu runtime není.
Note
prostředí Windows Runtime je založená na modelu COM. V terminologii COM je agilní třída zaregistrována s hodnotou ThreadingModel = Both. Další informace o modelech vláken a apartmánech v COM naleznete v článku Vysvětlení a používání modelů vláken v COM.
Příklady kódu
Pojďme použít ukázkovou implementaci třídy modulu runtime k zobrazení toho, jak C++/WinRT podporuje agilitu.
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
struct MyType : winrt::implements<MyType, IStringable>
{
winrt::hstring ToString(){ ... }
};
Vzhledem k tomu, že jsme se neodhlásili, je tato implementace agilní. winrt::implements je základní struktura, která implementuje IAgileObject a IMarshal. Implementace IMarshal používá CoCreateFreeThreadedMarshaler k provedení správné věci pro starší kód, který neví o IAgileObject.
Tento kód zkontroluje agilitu objektu. Volání IUnknown::as vyvolá výjimku, pokud myimpl není agilní.
winrt::com_ptr<MyType> myimpl{ winrt::make_self<MyType>() };
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.as<IAgileObject>() };
Místo zpracování výjimky můžete místo toho volat IUnknown::try_as .
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.try_as<IAgileObject>() };
if (iagileobject) { /* myimpl is agile. */ }
IAgileObject nemá žádné vlastní metody, takže s ním nemůžete moc dělat. Tato další varianta je pak typickější.
if (myimpl.try_as<IAgileObject>()) { /* myimpl is agile. */ }
IAgileObject je značkovací rozhraní. Pouhý úspěch nebo selhání dotazování na IAgileObject je rozsah informací a nástrojů, které z něj získáte.
Výslovný nesouhlas s podporou agilních objektů
Explicitně můžete vyjádřit výslovný nesouhlas s podporou agilních objektů předáním struktury značky winrt::non_agile jako argumentu šablony do základní třídy.
Pokud odvozujete přímo z winrt::implements.
struct MyImplementation: implements<MyImplementation, IStringable, winrt::non_agile>
{
...
}
Pokud vytváříte třídu runtime.
struct MyRuntimeClass: MyRuntimeClassT<MyRuntimeClass, winrt::non_agile>
{
...
}
Nezáleží na tom, kde se ve balíčku variadických parametrů objeví značková struktura.
Bez ohledu na to, jestli se odhlásíte z flexibility, můžete implementovat IMarshal sami. Můžete například použít značku winrt::non_agile , abyste se vyhnuli výchozí implementaci flexibility a implementovali IMarshal sami – třeba kvůli podpoře sémantiky marshal-by-value.
Agilní odkazy (winrt::agile_ref)
Pokud používáte objekt, který není agilní, ale potřebujete ho předat v některém potenciálně agilním kontextu, je jednou z možností použití šablony struktury winrt::agile_ref k získání agilního odkazu na instanci negilního typu nebo rozhraní negilního objektu.
NonAgileType nonagile_obj;
winrt::agile_ref<NonAgileType> agile{ nonagile_obj };
Nebo můžete použít pomocnou funkci winrt::make_agile.
NonAgileType nonagile_obj;
auto agile{ winrt::make_agile(nonagile_obj) };
V obou případech lze nyní agile volně předat vláknu v jiném apartmá a tam použít.
co_await resume_background();
NonAgileType nonagile_obj_again{ agile.get() };
winrt::hstring message{ nonagile_obj_again.Message() };
Volání agile_ref::get vrátí proxy server, který se může bezpečně použít v kontextu vlákna, ve kterém se volá get .
Důležitá rozhraní API
- IAgileObject – rozhraní
- IMarshal – rozhraní
- winrt::agile_ref šablona struktury
- winrt::implements šablona typu struct
- šablona funkce winrt::make_agile
- winrt::non_agile – struktura značek
- funkce winrt::Windows::Foundation::IUnknown::as
- winrt::Windows::Foundation::IUnknown::try_as function
Příbuzná témata
Windows developer