Sdílet prostřednictvím


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::exceptionnebo 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ů