Udostępnij za pośrednictwem


Podstawowe pojęcia w użyciu zarządzanych wyjątków

W tym temacie omówiono obsługi wyjątków w zarządzanych aplikacji.Oznacza to, że aplikacja, która została skompilowana z /clr opcję kompilatora.

W tym temacie

  • Wyrzucanie wyjątków w obszarze/CLR

  • Try/Catch bloki CLR rozszerzeń

Uwagi

Jeśli skompilować z /clr opcji, można obsługiwać wyjątków CLR, jak również standard obsługi wyjątków C++ i Strukturalna obsługa wyjątków (SEH).Wyjątek CLR jest każdy wyjątek typu zarządzanego.System::Exception klasa zawiera wiele użytecznych metod przetwarzania wyjątków CLR i jest zalecany jako klasa podstawowa dla klas wyjątków zdefiniowanych przez użytkownika.

Przechwytywanie wyjątków typów pochodnych interfejs nie jest obsługiwany w obszarze /clr.Ponadto common language runtime nie pozwalają na przechwytywać wyjątków przepełnienia stosu; wyjątek przepełnienia stosu zakończy proces.

Aby uzyskać więcej informacji o różnicach w obsługi wyjątków w zarządzanych i niezarządzanych aplikacji, zobacz różnice w wyjątek obsługi zachowanie w obszarze rozszerzenia zarządzane dla języka C++.

Wyrzucanie wyjątków w obszarze/CLR

Wyrażenie throw C++ jest rozszerzona throw uchwyt na typ CLR.Poniższy przykład tworzy typ wyjątku niestandardowe i następnie generuje instancję tego typu:

// clr_exception_handling.cpp
// compile with: /clr /c
ref struct MyStruct: public System::Exception {
public:
   int i;
};

void GlobalFunction() {
   MyStruct^ pMyStruct = gcnew MyStruct;
   throw pMyStruct;
}

Typ wartości musi ramkach przed pojazdu:

// clr_exception_handling_2.cpp
// compile with: /clr /c
value struct MyValueStruct {
   int i;
};

void GlobalFunction() {
   MyValueStruct v = {11};
   throw (MyValueStruct ^)v;
}

Try/Catch bloki CLR rozszerzeń

To samo Spróbuj/połowu struktury bloku mogą służyć do połowu zarówno CLR i macierzystych wyjątki:

// clr_exception_handling_3.cpp
// compile with: /clr
using namespace System;
ref struct MyStruct : public Exception {
public:
   int i;
};

struct CMyClass {
public:
   double d;
};

void GlobalFunction() {
   MyStruct^ pMyStruct = gcnew MyStruct;
   pMyStruct->i = 11;
   throw pMyStruct;
}

void GlobalFunction2() {
   CMyClass c = {2.0};
   throw c;
}

int main() {
   for ( int i = 1; i >= 0; --i ) {
      try {
         if ( i == 1 )
            GlobalFunction2();
         if ( i == 0 )
            GlobalFunction();
      }
      catch ( CMyClass& catchC ) {
         Console::WriteLine( "In 'catch(CMyClass& catchC)'" );
         Console::WriteLine( catchC.d );
      }
      catch ( MyStruct^ catchException ) {
         Console::WriteLine( "In 'catch(MyStruct^ catchException)'" );
         Console::WriteLine( catchException->i );
      }
   }
}

df24ysb6.collapse_all(pl-pl,VS.110).gifDane wyjściowe

In 'catch(CMyClass& catchC)'
2
In 'catch(MyStruct^ catchException)'
11

df24ysb6.collapse_all(pl-pl,VS.110).gifKolejność niekontrolowanej obiektów C++

Niekontrolowanej występuje dla obiektów C++ z destruktory, które mogą być na stosie czasu między throwing funkcji i funkcji obsługi.Ponieważ typu CLR są przydzielane na stercie, niekontrolowanej nie dotyczą ich.

Kolejnooć zdarzeń dla thrown wyjątek jest następująca:

  1. Środowisko wykonawcze przeprowadza stosu dla klauzuli catch właściwe lub z SEH, z wyjątkiem filtr SEH do połowu wyjątek.Catch klauzul przeszukiwany w pierwszej kolejności leksykalne zamówienia, a następnie dynamicznie w dół stosu wywołań.

  2. Poprawna obsługa zostanie znaleziony, stosu po zwiniętej do tego punktu.Dla każdego wywołania funkcji na stosie są zniszczone jego obiektów lokalnych i __finally bloki są wykonywane, od najbardziej na zewnątrz zagnieżdżone.

  3. Gdy stos zwiniętej, klauzuli catch jest wykonywany.

df24ysb6.collapse_all(pl-pl,VS.110).gifPołowu niezarządzanego typów

Typ obiektu niezarządzany jest generowany, jest pakowane z wyjątkiem typu System::Runtime.InteropServices::SEHException.Podczas wyszukiwania do właściwego połowu klauzuli, istnieją dwie możliwości.

  • Jeśli typem macierzystym C++, wyjątek jest następnie rozpakować i w porównaniu z typem napotkał.Porównanie to umożliwia typem macierzystym C++ poławiane w normalny sposób.

  • Jednakże jeśli połowu klauzuli typu SEHException lub dowolnego z jej klas podstawowych najpierw zbadać, klauzula przechwytuje wyjątek.W związku z tym należy umieścić wszystkie klauzule połowu, najpierw połowów macierzystym C++ typów przed żadnego połowu klauzul typu CLR.

Należy zauważyć, że

catch(Object^)

i

catch(...)

będzie zarówno połowu dowolnego typu thrown, łącznie z wyjątkami SEH.

Jeśli typ niezarządzany jest złowionych przez catch(Object^), nie spowoduje zniszczenie obiektu thrown.

Gdy rzuca lub połowu niezarządzanych wyjątki, zaleca się używanie /EHsc opcję kompilatora, zamiast /EHs lub /EHa.

Zobacz też

Informacje

safe_cast (C++ Component Extensions)

Obsługa wyjątków w programie Visual C++

Inne zasoby

Obsługa wyjątków (C++ Component Extensions)