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.
Foutafhandeling in C++/CX is gebaseerd op uitzonderingen. Op het meest fundamentele niveau rapporteren Windows Runtime-onderdelen fouten als HRESULT-waarden. In C++/CX worden deze waarden geconverteerd naar sterk getypte uitzonderingen die een HRESULT-waarde en een tekenreeksbeschrijving bevatten die u programmatisch kunt openen. Uitzonderingen worden geïmplementeerd als een ref class uitzondering die is afgeleid van Platform::Exception. De Platform naamruimte definieert afzonderlijke uitzonderingsklassen voor de meest voorkomende HRESULT-waarden. Alle andere waarden worden gerapporteerd via de Platform::COMException klasse. Alle uitzonderingsklassen hebben een uitzonderingsveld::HResult dat u kunt gebruiken om het oorspronkelijke HRESULT op te halen. U kunt ook aanroepstackgegevens voor gebruikerscode onderzoeken in het foutopsporingsprogramma waarmee de oorspronkelijke bron van de uitzondering kan worden vastgesteld, zelfs als deze afkomstig is uit code die is geschreven in een andere taal dan C++.
Uitzonderingen
In uw C++-programma kunt u een uitzondering genereren en vangen die afkomstig is van een Windows Runtime-bewerking, een uitzondering die is afgeleid van std::exceptionof een door de gebruiker gedefinieerd type. U moet alleen een Windows Runtime-uitzondering genereren wanneer deze de grens van de binaire interface (ABI) van de toepassing overschrijdt, bijvoorbeeld wanneer de code die uw uitzondering onderschept, wordt geschreven in JavaScript. Wanneer een niet-Windows Runtime C++-uitzondering de ABI-grens bereikt, wordt de uitzondering omgezet in een Platform::FailureException uitzondering, die een E_FAIL HRESULT vertegenwoordigt. Zie Windows Runtime-onderdelen maken in C++voor meer informatie over de ABI.
U kunt een Platform::Exception declareren met behulp van een van de twee constructors die een HRESULT-parameter of een HRESULT-parameter en een Parameter Platform::String^ gebruiken die via de ABI kunnen worden doorgegeven aan elke Windows Runtime-app die deze verwerkt. U kunt ook een uitzondering declareren met behulp van een van de twee uitzonderingen::CreateException-methode overbelasten die een HRESULT-parameter of een HRESULT-parameter en een Platform::String^ parameter gebruiken.
Standaard uitzonderingen
C++/CX ondersteunt een set standaard uitzonderingen die typische HRESULT-fouten vertegenwoordigen. Elke standaarduitzondering is afgeleid van Platform::COMException, die op zijn beurt is afgeleid van Platform::Exception. Wanneer u een uitzondering over de ABI-grens genereert, moet u een van de standaard uitzonderingen genereren.
U kunt uw eigen uitzonderingstype niet afleiden van Platform::Exception. Als u een aangepaste uitzondering wilt genereren, gebruikt u een door de gebruiker gedefinieerde HRESULT om een COMException object te maken.
De volgende tabel bevat de standaard uitzonderingen.
| Naam | Onderliggende HRESULT | Beschrijving |
|---|---|---|
| COMException | door de gebruiker gedefinieerde hresult- | Gegenereerd wanneer een niet-herkende HRESULT wordt geretourneerd vanuit een COM-methodeaanroep. |
| AccessDeniedException | E_ACCESSDENIED | Gegenereerd wanneer de toegang tot een resource of functie wordt geweigerd. |
| ChangedStateException | E_CHANGED_STATE (veranderde toestand) | Gegenereerd wanneer methoden van een verzamelings-iterator of een verzamelingsweergave worden aangeroepen nadat de bovenliggende verzameling is gewijzigd, waardoor de resultaten van de methode ongeldig worden. |
| ClassNotRegisteredException | REGDB_E_CLASSNOTREG | Gegenereerd wanneer een COM-klasse niet is geregistreerd. |
| DisconnectedException | RPC_E_DISCONNECTED | Gegenereerd wanneer een object wordt losgekoppeld van de clients. |
| FailureException | E_FAIL | Gegenereerd wanneer een bewerking mislukt. |
| InvalidArgumentException | E_INVALIDARG | Gegenereerd wanneer een van de argumenten die aan een methode worden verstrekt, niet geldig is. |
| InvalidCastException | E_NOINTERFACE | Gegenereerd wanneer een type niet naar een ander type kan worden gegooid. |
| NotImplementedException | E_NOTIMPL | Gegenereerd als er geen interfacemethode is geïmplementeerd in een klasse. |
| NullReferenceException | E_POINTER | Gegenereerd wanneer er een poging is om een verwijzing naar een null-object ongedaan te maken. |
| ObjectDisposedException | RO_E_CLOSED | Gegenereerd wanneer een bewerking wordt uitgevoerd op een verwijderd object. |
| OperationCanceledException | E_ABORT | Gegenereerd wanneer een bewerking wordt afgebroken. |
| OutOfBoundsException | E_BOUNDS | Gegenereerd wanneer een bewerking toegang probeert te krijgen tot gegevens buiten het geldige bereik. |
| OutOfMemoryException | E_OUTOFMEMORY | Gegenereerd wanneer er onvoldoende geheugen is om de bewerking te voltooien. |
| WrongThreadException | RPC_E_WRONG_THREAD | Gegenereerd wanneer een thread wordt aangeroepen via een interfaceaanwijzer die voor een proxyobject is dat niet tot het appartement van de thread behoort. |
Eigenschappen van HResult en Bericht
Alle uitzonderingen hebben een HResult-eigenschap en een berichteigenschap . De eigenschap Exception::HResult haalt de onderliggende numerieke HRESULT-waarde van de uitzondering op. De eigenschap Uitzondering::Bericht haalt de door het systeem geleverde tekenreeks op die de uitzondering beschrijft. In Windows 8 is het bericht alleen beschikbaar in het foutopsporingsprogramma en is het alleen-lezen. Dit betekent dat u deze niet kunt wijzigen wanneer u de uitzondering afwerpt. In Windows 8.1 hebt u programmatisch toegang tot de berichtreeks en kunt u een nieuw bericht opgeven als u de uitzondering afwerpt. Betere callstack-informatie is ook beschikbaar in het foutopsporingsprogramma, waaronder callstacks voor asynchrone methodeaanroepen.
Voorbeelden
In dit voorbeeld ziet u hoe u een Windows Runtime-uitzondering genereert voor synchrone bewerkingen:
String^ Class1::MyMethod(String^ argument)
{
if (argument->Length() == 0)
{
auto e = ref new Exception(-1, "I'm Zork bringing you this message from across the ABI.");
//throw ref new InvalidArgumentException();
throw e;
}
return MyMethodInternal(argument);
}
In het volgende voorbeeld ziet u hoe u de uitzondering kunt ondervangen.
void Class2::ProcessString(String^ input)
{
String^ result = nullptr;
auto obj = ref new Class1();
try
{
result = obj->MyMethod(input);
}
catch (/*InvalidArgument*/Exception^ e)
{
// Handle the exception in a way that's appropriate
// for your particular scenario. Assume
// here that this string enables graceful
// recover-and-continue. Why not?
result = ref new String(L"forty two");
// You can use Exception data for logging purposes.
Windows::Globalization::Calendar calendar;
LogMyErrors(calendar.GetDateTime(), e->HResult, e->Message);
}
// Execution continues here in both cases.
//#include <string>
std::wstring ws(result->Data());
//...
}
Als u uitzonderingen wilt ondervangen die worden gegenereerd tijdens een asynchrone bewerking, gebruikt u de taakklasse en voegt u een vervolg voor foutafhandeling toe. De foutafhandeling vervolg marshals uitzonderingen die worden gegenereerd op andere threads terug naar de aanroepende thread, zodat u alle potentiële uitzonderingen op slechts één punt in uw code kunt afhandelen. Zie Asynchrone programmering in C++voor meer informatie.
UnhandledErrorDetected-gebeurtenis
In Windows 8.1 kunt u zich abonneren op de statische gebeurtenis Windows:::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected , die toegang biedt tot niet-verwerkte fouten die het proces gaan afbreken. Ongeacht waar de fout vandaan komt, wordt deze handler bereikt als een Windows::ApplicationModel::Core::UnhandledError-object dat wordt doorgegeven met de gebeurtenis args. Wanneer u het object aanroept PropagatePlatform::*Exception , wordt een van het type gemaakt en gegenereerd dat overeenkomt met de foutcode. In de catch-blokken kunt u indien nodig de gebruikersstatus opslaan en vervolgens toestaan dat het proces wordt beëindigd door aan te roepen throwof iets te doen om het programma weer in een bekende status te krijgen. In het volgende voorbeeld ziet u het basispatroon:
In app.xaml.h:
void OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e);
In app.xaml.cpp:
// Subscribe to the event, for example in the app class constructor:
Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected += ref new EventHandler<UnhandledErrorDetectedEventArgs^>(this, &App::OnUnhandledException);
// Event handler implementation:
void App::OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e)
{
auto err = e->UnhandledError;
if (!err->Handled) //Propagate has not been called on it yet.
{
try
{
err->Propagate();
}
// Catch any specific exception types if you know how to handle them
catch (AccessDeniedException^ ex)
{
// TODO: Log error and either take action to recover
// or else re-throw exception to continue fail-fast
}
}
Opmerkingen
C++/CX maakt geen gebruik van de finally component.
Zie ook
Naslaginformatie over C++/CX-taal
Naslaginformatie over naamruimten