Jeśli masz aplikację z jednym gwintem, możesz użyć prostej funkcji prób/catch w funkcji głównej, jednak nie obejmuje ona wyjątków, które mogą być wyrzucane poza główną funkcję, na innych wątkach, na przykład (jak zauważono w innych komentarzach).Ten kod demonstruje, w jaki sposób wyjątek może spowodować zakończenie działania aplikacji, nawet jeśli próbowałeś obsłużyć ją w Main (zwróć uwagę, jak program kończy pracę z wdziękiem, jeśli naciśniesz klawisz enter i zezwolisz aplikacji na zakończenie z rozwagą przed wystąpieniem wyjątku, ale jeśli pozwolisz jej działać , to kończy się dość nieszczęśliwie):
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24/i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
Możesz otrzymywać powiadomienia, gdy inny wątek zgłasza wyjątek, aby wykonać niektóre oczyścić przed zakończeniem aplikacji, ale o ile wiem, nie można, od aplikacji konsoli , wymuś kontynuację działania aplikacji, jeśli nie potraktujesz wyjątku w wątku, z którego jest on wysyłany, bez użycia pewnych niejasnych opcji zgodności, aby aplikacja zachowywała się tak, jak w przypadku .NET 1.x. Ten kod demonstruje jak główny wątek może zostać powiadomiony wyjątków pochodzących z innych wątków, ale nadal będą zakończyć nieszczęśliwie:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Notified of a thread exception... application is terminating.");
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24/i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
Więc moim zdaniem, najczystszy sposób obsłużyć go w aplikacji konsoli jest zapewnienie że każdy wątek ma obsługi wyjątku na poziomie root:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
try
{
for (int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24/i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception on the other thread");
}
}
Argh, głupi błąd, muszę dodać AddHandler przed AppDomain.CurrentDomain zobaczyć „UnhandledException” w VB.NET ... –
I wdrożone co zaproponowałeś tutaj, ale nie chcę opuszczać aplikacji. Po prostu chcę go zarejestrować i kontynuować proces (bez 'Console.ReadLine()' lub jakichkolwiek innych zakłóceń w przepływie programu.Jednakże otrzymuję wyjątek ponownie wznosząc się ponownie i znowu, i znowu –
@Shahrooz Jefri: Nie można kontynuować, gdy pojawi się nieobsługiwany wyjątek: Stos jest pomieszany, a to jest terminal.Jeśli masz serwer, to co możesz zrobić w UnhandledExceptionTrapper, to zrestartuj program z tymi samymi argumentami wiersza poleceń: –