Výjimky (C++/CX)
Zpracování chyb v C++/CX je založeno na výjimkách. Na nejzákladnější úrovni prostředí Windows Runtime komponenty hlásí chyby jako hodnoty HRESULT. V jazyce C++/CX se tyto hodnoty převedou na výjimky silného typu, které obsahují hodnotu HRESULT a popis řetězce, ke kterému máte přístup prostřednictvím kódu programu. Výjimky jsou implementovány jako odvozené ref class
od Platform::Exception
. Obor Platform
názvů definuje jedinečné třídy výjimek pro nejběžnější hodnoty HRESULT; všechny ostatní hodnoty jsou hlášeny prostřednictvím Platform::COMException
třídy. Všechny třídy výjimek mají pole Exception::HResult , které můžete použít k načtení původní hodnoty HRESULT. Můžete také prozkoumat informace o zásobníku volání pro uživatelský kód v ladicím programu, který může pomoct určit původní zdroj výjimky, i když pochází z kódu napsaného v jiném jazyce než C++.
Výjimky
V programu C++ můžete vyvolat a zachytit výjimku, která pochází z operace prostředí Windows Runtime, výjimku odvozenou od std::exception
nebo uživatelem definovaný typ. Výjimku prostředí Windows Runtime musíte vyvolat pouze v případě, že překročí hranice binárního rozhraní aplikace (ABI), například když kód, který zachytí vaši výjimku, je napsaný v JavaScriptu. Pokud výjimka C++ bez prostředí Windows Runtime dosáhne hranice ABI, výjimka se přeloží na Platform::FailureException
výjimku, která představuje E_FAIL HRESULT. Další informace o ABI naleznete v tématu Vytváření komponent prostředí Windows Runtime v jazyce C++.
Platform::Exception můžete deklarovat pomocí jednoho ze dvou konstruktorů, které přebírají buď parametr HRESULT, nebo parametr HRESULT a parametr Platform::String^, který lze předat přes ABI libovolné aplikaci prostředí Windows Runtime, která ji zpracovává. Nebo můžete deklarovat výjimku pomocí jednoho ze dvou exception::CreateException přetížení metody , které přebírají buď PARAMETR HRESULT, nebo HRESULT parametr a Platform::String^
parametr.
Standardní výjimky
C++/CX podporuje sadu standardních výjimek, které představují typické chyby HRESULT. Každá standardní výjimka je odvozena z platformy::COMException, která je zase odvozena od Platform::Exception
. Když vyvoláte výjimku přes hranici ABI, musíte vyvolat jednu ze standardních výjimek.
Nelze odvodit vlastní typ výjimky z Platform::Exception
. Chcete-li vyvolat vlastní výjimku, použijte uživatelem definovanou HRESULT k vytvoření objektu COMException
.
Následující tabulka uvádí standardní výjimky.
Název | Podkladová hodnota HRESULT | Popis |
---|---|---|
Výjimka MODELU COM | uživatelem definovaný hresult | Vyvolá se, když se z volání metody COM vrátí nerozpoznaná hodnota HRESULT. |
AccessDeniedException | E_ACCESSDENIED | Vyvolá se při odepření přístupu k prostředku nebo funkci. |
ChangedStateException | E_CHANGED_STATE | Vyvolá se při vyvolání metod iterátoru kolekce nebo zobrazení kolekce po změně nadřazené kolekce, čímž dojde k zneplatnění výsledků metody. |
ClassNotRegisteredException | REGDB_E_CLASSNOTREG | Vyvolá se, když nebyla zaregistrována třída MODELU COM. |
DisconnectedException | RPC_E_DISCONNECTED | Vyvolá se při odpojení objektu od klientů. |
FailureException | E_FAIL | Vyvolá se při selhání operace. |
InvalidArgumentException | E_INVALIDARG | Vyvolá se, pokud některý z argumentů zadaných metodě není platný. |
InvalidCastException | E_NOINTERFACE | Vyvolá se, když typ nelze přetypovat na jiný typ. |
NotImplementedException | E_NOTIMPL | Vyvolá se, pokud metoda rozhraní nebyla implementována ve třídě. |
NullReferenceException | E_POINTER | Vyvolá se při pokusu o zrušení odkazu na odkaz na objekt null. |
ObjectDisposedException | RO_E_CLOSED | Vyvolá se při provedení operace u odstraněného objektu. |
OperationCanceledException | E_ABORT | Vyvolá se při přerušení operace. |
OutOfBoundsException | E_BOUNDS | Vyvolá se, když se operace pokusí o přístup k datům mimo platný rozsah. |
OutOfMemoryException | E_OUTOFMEMORY | Vyvolá se, když není dostatek paměti k dokončení operace. |
Nesprávná výjimkaThreadException | RPC_E_WRONG_THREAD | Vyvolá se, když vlákno volá prostřednictvím ukazatele rozhraní, který je pro objekt proxy, který nepatří do bytu vlákna. |
Vlastnosti HResult a Message
Všechny výjimky mají HResult vlastnost a Message vlastnost. Vlastnost Exception::HResult získá základní číselnou hodnotu HRESULT výjimky. Vlastnost Exception::Message získá řetězec zadaný systémem, který popisuje výjimku. Ve Windows 8 je zpráva k dispozici pouze v ladicím programu a je jen pro čtení. To znamená, že při opětovném zvětšování výjimky ho nemůžete změnit. Ve Windows 8.1 máte přístup k řetězci zprávy prostřednictvím kódu programu a pokud znovu vytvoříte výjimku, zadejte novou zprávu. V ladicím programu jsou také k dispozici lepší informace o voláních volání, včetně volání volání asynchronní metody.
Příklady
Tento příklad ukazuje, jak vyvolat výjimku prostředí Windows Runtime pro synchronní operace:
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);
}
Další příklad ukazuje, jak zachytit výjimku.
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());
//...
}
Chcete-li zachytit výjimky, které jsou vyvolány během asynchronní operace, použijte třídu úlohy a přidejte pokračování zpracování chyb. Výjimky zařazování pokračování zpracování chyb, které jsou vyvolány na jiných vláknech zpět do volajícího vlákna, takže můžete zpracovat všechny potenciální výjimky pouze na jednom místě v kódu. Další informace naleznete v tématu Asynchronní programování v jazyce C++.
Neošetřená událostErrorDetected
Ve Windows 8.1 se můžete přihlásit k odběru statické události Windows::ApplicationModel::Core:CoreApplication::UnhandledErrorDetected , která poskytuje přístup k neošetřeným chybám, které se chystá proces snížit. Bez ohledu na to, kde chyba pochází, dosáhne této obslužné rutiny jako Windows::ApplicationModel::Core::UnhandledError objekt, který se předává s událostí args. Při volání Propagate
objektu se vytvoří a vyvolá Platform::*Exception
typ odpovídající kódu chyby. V blocích catch můžete v případě potřeby uložit stav uživatele a pak buď povolit ukončení procesu voláním throw
, nebo něco udělat, aby se program vrátil do známého stavu. Následující příklad ukazuje základní vzor:
V souboru app.xaml.h:
void OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e);
V 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
}
}
Poznámky
C++/CX nepoužívá klauzuli finally
.
Viz také
Referenční zdroje k jazyku C++/CX
Referenční informace o oborech názvů