Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In de meeste gevallen kan een exemplaar van een Windows Runtime-klasse worden geopend vanuit elke thread (net als de meeste standaard C++-objecten). Zo'n Windows Runtime-klasse is wendbaar. Slechts een klein aantal Windows Runtime klassen die met Windows worden verzonden, zijn niet flexibel, maar wanneer u ze gebruikt, moet u rekening houden met hun threadingmodel en marshalinggedrag (marshaling geeft gegevens door over een appartementgrens). Het is een goede standaardinstelling voor elke Windows Runtime object om flexibel te zijn, dus uw eigen C++/WinRT-typen zijn standaard flexibel.
Maar je kunt ervoor kiezen dit niet te doen. Je hebt misschien een dwingende reden om te eisen dat een object van jouw type zich bijvoorbeeld in een bepaalde single-threaded apartment bevindt. Dit heeft meestal te maken met eisen inzake re-entrantie. Maar in toenemende mate bieden zelfs gebruikersinterface-API's flexibele objecten. Over het algemeen is flexibiliteit de eenvoudigste en meest presterende optie. Wanneer u een activeringsfactory implementeert, moet deze ook flexibel zijn, zelfs als uw bijbehorende runtimeklasse dat niet is.
Note
De Windows Runtime is gebaseerd op COM. In COM-termen wordt een agile-klasse geregistreerd bij ThreadingModel = Beide. Zie Understanding and Using COM Threading Models voor meer informatie over COM-threadingmodellen en apartments.
Codevoorbeelden
Laten we een voorbeeldimplementatie van een runtimeklasse gebruiken om te laten zien hoe C++/WinRT flexibiliteit ondersteunt.
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
struct MyType : winrt::implements<MyType, IStringable>
{
winrt::hstring ToString(){ ... }
};
Omdat we ons niet hebben afgemeld, is deze implementatie flexibel. De winrt::implementeert basisstruct implementeert IAgileObject en IMarshal. De IMarshal-implementatie maakt gebruik van CoCreateFreeThreadedMarshaler om het juiste te doen voor verouderde code die niet weet over IAgileObject.
Met deze code wordt een object gecontroleerd op flexibiliteit. De aanroep van IUnknown::as genereert een uitzondering als myimpl niet agile is.
winrt::com_ptr<MyType> myimpl{ winrt::make_self<MyType>() };
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.as<IAgileObject>() };
In plaats van een uitzondering af te handelen, kunt u in plaats daarvan IUnknown::try_as aanroepen.
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.try_as<IAgileObject>() };
if (iagileobject) { /* myimpl is agile. */ }
IAgileObject heeft geen eigen methoden, dus u kunt er niet veel mee doen. Deze volgende variant is dan gebruikelijker.
if (myimpl.try_as<IAgileObject>()) { /* myimpl is agile. */ }
IAgileObject is een markeringsinterface. Het loutere succes of falen van het uitvoeren van query's voor IAgileObject is de omvang van de informatie en het hulpprogramma dat u krijgt.
Afmelden voor agile-objectondersteuning
U kunt er expliciet voor kiezen af te zien van ondersteuning voor agile objecten door de markeringsstruct winrt::non_agile op te geven als sjabloonargument voor uw basisklasse.
Als u rechtstreeks overerft van winrt::implements.
struct MyImplementation: implements<MyImplementation, IStringable, winrt::non_agile>
{
...
}
Als u een runtimeklasse schrijft.
struct MyRuntimeClass: MyRuntimeClassT<MyRuntimeClass, winrt::non_agile>
{
...
}
Het maakt niet uit waar in het variadische parameterpakket de marker-struct voorkomt.
Of u zich al dan niet afmeldt voor flexibiliteit, u kunt IMarshal zelf implementeren. U kunt bijvoorbeeld de winrt::non_agile markering gebruiken om de standaardimplementatie van flexibiliteit te voorkomen en IMarshal zelf te implementeren, misschien om semantiek van marshal-by-value te ondersteunen.
Agile-verwijzingen (winrt::agile_ref)
Als u een object gebruikt dat niet flexibel is, maar u het in een potentieel flexibele context moet doorgeven, kunt u de winrt::agile_ref-structsjabloon gebruiken om een agile-verwijzing naar een exemplaar van een niet-agile-type of een interface van een niet-agile-object te verkrijgen.
NonAgileType nonagile_obj;
winrt::agile_ref<NonAgileType> agile{ nonagile_obj };
U kunt ook de helperfunctie winrt::make_agile gebruiken.
NonAgileType nonagile_obj;
auto agile{ winrt::make_agile(nonagile_obj) };
In beide gevallen agile kan nu vrij worden doorgegeven aan een draad in een ander appartement en daar gebruikt.
co_await resume_background();
NonAgileType nonagile_obj_again{ agile.get() };
winrt::hstring message{ nonagile_obj_again.Message() };
De agile_ref::get-aanroep retourneert een proxy die veilig kan worden gebruikt in de threadcontext waarin get wordt aangeroepen.
Belangrijke API's
- Interface IAgileObject
- IMarshal-interface
- winrt::agile_ref struct-sjabloon
- winrt::implementeert de structsjabloon
- winrt::make_agile functiesjabloon
- winrt::non_agile marker struct
- winrt::Windows::Foundation::IUnknown::as function
- winrt::Windows::Foundation::IUnknown::try_as, functie
Verwante onderwerpen
Windows developer