Megosztás a következőn keresztül:


Kivételek (C++/CX)

A C++/CX hibakezelése kivételeken alapul. A windowsos futtatókörnyezet összetevői a legalapvetőbb szinten HRESULT értékekként jelentik a hibákat. A C++/CX fájlban ezek az értékek erősen beírt kivételekké alakulnak, amelyek egy HRESULT értéket és egy programozott módon elérhető sztringleírást tartalmaznak. A kivételek a ref class következőből Platform::Exceptionszármaznak: . A Platform névtér különböző kivételosztályokat határoz meg a leggyakoribb HRESULT értékekhez; az összes többi értéket az Platform::COMException osztályon keresztül jelenti. Minden kivételosztály rendelkezik kivétel::HResult mezővel, amellyel lekérheti az eredeti HRESULT-t. A hibakeresőben megvizsgálhatja a felhasználói kód hívásveremadatait is, amelyek segítenek a kivétel eredeti forrásának rögzítésében, még akkor is, ha az a C++-tól eltérő nyelven írt kódból származik.

Kivételek

A C++ programban windowsos futtatókörnyezeti műveletből, vagy felhasználó által definiált típusból std::exceptionszármazó kivételt hozhat létre és foghat ki. Windows futtatókörnyezeti kivételt csak akkor kell megadnia, ha az átlépi az alkalmazás bináris interfészének (ABI) határát, például ha a kivételt elkapó kód JavaScriptben van megírva. Amikor egy nem Windows-futtatókörnyezeti C++ kivétel eléri az ABI határát, a kivétel kivételré Platform::FailureException lesz lefordítva, amely egy E_FAIL HRESULT-ot jelöl. További információ az ABI-ról: Windows futtatókörnyezeti összetevők létrehozása a C++-ban.

A Platform::Exception paraméter deklarálható egy HRESULT paramétert vagy egy HRESULT paramétert és egy platform::String^ paramétert tartalmazó két konstruktor egyikével, amely az ABI-n keresztül továbbítható bármely olyan Windows Futtatókörnyezeti alkalmazásnak, amely kezeli azt. Deklarálhat kivételt két kivétel::CreateException metódus túlterhelések egyikével, amelyek egy HRESULT paramétert, vagy egy HRESULT paramétert és egy paramétert Platform::String^ vesznek fel.

Standard kivételek

A C++/CX szabványkivételeket támogat, amelyek tipikus HRESULT-hibákat jelölnek. Minden standard kivétel a Platform::COMException függvényből származik, amely a következőből Platform::Exceptionszármazik: . Ha kivételt ad át az ABI-határon, a szokásos kivételek egyikét kell megadnia.

A saját kivételtípus nem származtatható a fájlból Platform::Exception. Egyéni kivétel létrehozásához használjon felhasználó által definiált HRESULT-t egy COMException objektum létrehozásához.

Az alábbi táblázat a szokásos kivételeket sorolja fel.

Név Mögöttes HRESULT Leírás
COMException felhasználó által definiált hresult A nem felismert HRESULT egy COM-metódushívásból való visszaadásakor jön létre.
AccessDeniedException E_ACCESSDENIED Akkor jelenik meg, ha a hozzáférés megtagadva van egy erőforráshoz vagy szolgáltatáshoz.
ChangedStateException ÁLLAPOT_VÁLTOZÁS_TÖRTÉNT A rendszer a szülőgyűjtemény módosítása után meghívja a gyűjtemény iterátorának vagy gyűjteménynézetének metódusait, ezáltal érvényteleníti a metódus eredményeit.
ClassNotRegisteredException REGDB_E_CLASSNOTREG Akkor van beállítva, ha egy COM-osztály nincs regisztrálva.
DisconnectedException RPC_E_DISCONNECTED Egy objektum leválasztása az ügyfelekről.
FailureException E_FAIL A művelet meghiúsulásakor a rendszer eldobja.
ÉrvénytelenArgumentumKivétel E_INVALIDARG (Érvénytelen argumentum) A metódushoz megadott argumentumok egyike érvénytelen.
InvalidCastException E_NOINTERFACE Akkor dobják ki, ha egy típust nem lehet más típusra leadni.
NotImplementedException E_NOTIMPL (Nem megvalósított funkció) Akkor kerül végrehajtásra, ha egy interfészmetódus nem lett implementálva egy osztályon.
NullReferenceException E_POINTER Null objektumhivatkozás hivatkozásának törlésére tett kísérlet esetén történik.
ObjectDisposedException RO_E_CLOSED Eldobva, amikor egy műveletet hajtanak végre egy megsemmisített objektumon.
OperationCanceledException E_ABORT (Megszakítási hibakód) A művelet megszakításakor történik.
OutOfBoundsException E_BOUNDS Akkor történik, amikor egy művelet megpróbál hozzáférni az érvényes tartományon kívüli adatokhoz.
OutOfMemoryException E_OUTOFMEMORY Ha nincs elegendő memória a művelet végrehajtásához.
WrongThreadException RPC_E_WRONG_THREAD Akkor dobott, amikor egy szál egy interfészmutatón keresztül telefonál, amely olyan proxyobjektumhoz tartozik, amely nem tartozik a szál lakásához.

A HResult és az Üzenet tulajdonságai

Minden kivételhez HResult tulajdonság és Üzenet tulajdonság tartozik. A Kivétel::HResult tulajdonság lekéri a kivétel mögöttes numerikus HRESULT-értékét. A Kivétel::Üzenet tulajdonság lekéri a kivételt leíró rendszer által megadott sztringet. Windows 8 rendszerben az üzenet csak a hibakeresőben érhető el, és írásvédett. Ez azt jelenti, hogy a kivétel ismételt létrehozásakor nem módosíthatja azt. A Windows 8.1-ben programozott módon érheti el az üzenetsztringet, és új üzenetet jeleníthet meg, ha újrakezdi a kivételt. A hibakeresőben jobb híváshívási információk is elérhetők, beleértve az aszinkron metódushívások hívásait is.

Példák

Ez a példa bemutatja, hogyan lehet windowsos futtatókörnyezeti kivételt kivenni a szinkron műveletekhez:

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);
}

A következő példa bemutatja, hogyan lehet elkapni a kivételt.

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());
    //...
}

Az aszinkron művelet során megjelenő kivételek fogásához használja a feladatosztályt, és adjon hozzá egy hibakezelési folytatást. A hibakezelési folytatás a többi szálra a hívó szálra visszadobott kivételeket rögzíti, így a kód egyetlen pontján kezelheti az összes lehetséges kivételt. További információ: Aszinkron programozás a C++-ban.

UnhandledErrorDetected esemény

A Windows 8.1-ben előfizethet a Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected statikus eseményre , amely hozzáférést biztosít a folyamat leállítására készülő nem kezelt hibákhoz. A hiba forrásától függetlenül windowsos::ApplicationModel::Core::UnhandledError objektumként éri el ezt a kezelőt, amely az esemény args-ével lett átadva. Amikor meghívja Propagate az objektumot, az létrehoz és eldob egy Platform::*Exception , a hibakódnak megfelelő típust. A fogási blokkokban szükség esetén mentheti a felhasználói állapotot, majd engedélyezheti a folyamat leállítását hívással throw, vagy tehet valamit a program ismert állapotba való visszaállításához. Az alábbi példa az alapmintát mutatja be:

Az app.xaml.h fájlban:

void OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e);

A 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
    }
}

Megjegyzések

A C++/CX nem használja a záradékot finally .

Lásd még

C++/CX nyelvi referencia
Névterek – referencia