Finalizery są zawsze wywoływane przez framework .net, więc sekwencja może być poza kontrolą; nawet jeśli konstruktor się nie powiódł, destruktor nadal może zostać wywołany.C#: Jak radzić sobie z wyjątkami finalizera z biblioteki innej firmy?
Może to przysporzyć problemów, gdy takie wyjątki finalizatora pochodzą z biblioteki innej firmy: nie mogę znaleźć sposobu na ich obsłużenie!
Na przykład w poniższym kodzie, chociaż konstruktor klasy A zawsze zgłasza wyjątek i zawiedzie, finalizator A zostanie wywołany przez framework .net, również ~ B() zostanie wywołane, ponieważ A ma właściwość typu B .
class Program // my code
{
static void Main(string[] args)
{
A objA;
try
{
objA = new A();
}
catch (Exception)
{
}
; // when A() throws an exception, objA is null
GC.Collect(); // however, this can force ~A() and ~B() to be called.
Console.ReadLine();
}
}
public class A // 3rd-party code
{
public B objB;
public A()
{
objB = new B(); // this will lead ~B() to be called.
throw new Exception("Exception in A()");
}
~A() // called by .net framework
{
throw new Exception("Exception in ~A()"); // bad coding but I can't modify
}
}
public class B // 3rd-party code
{
public B() { }
~B() // called by .net framework
{
throw new Exception("Exception in ~B()"); // bad coding but I can't modify
}
}
Jeśli to mój kod, to jest trochę łatwiej - mogę użyć try-catch w finalizatorów, przynajmniej mogę zrobić rejestrowanie - mogę pozwolić wyjątek awarię programu, aby odkryć Błąd jak najszybciej - lub jeśli chcę "tolerować" wyjątek, mogę mieć try-catch, aby wyłączyć wyjątek i mieć zgrabne wyjście.
Ale jeśli A i B są klasami z biblioteki 3rd party, nie mogę nic zrobić! Nie mogę kontrolować wyjątku, nie mogę ich złapać, więc nie mogę go zarejestrować ani ukryć!
Co mogę zrobić?
+1 Interesujący problem (aw międzyczasie podnieś pilny raport o błędach u dostawców biblioteki, która dostarcza "A" i "B"). – Ergwun
^^ - Świetny punkt. Musi być prawdziwą odpowiedzią. –