Jeśli masz aplikację jednowątkową, możesz użyć prostej try / catch w funkcji Main, jednak nie obejmuje to wyjątków, które mogą być zgłaszane poza funkcją Main, na przykład w innych wątkach (jak zaznaczono w innych komentarze). Ten kod pokazuje, w jaki sposób wyjątek może spowodować zamknięcie aplikacji, nawet jeśli próbujesz obsłużyć go w Main (zwróć uwagę, jak program kończy działanie z wdziękiem, jeśli naciśniesz enter i zezwolisz aplikacji z wdziękiem wyjść, zanim wystąpi wyjątek, ale jeśli pozwolisz mu działać) , kończy się dość niefortunnie):
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 otrzymać powiadomienie, kiedy inny wątek zgłosi wyjątek, aby wykonać pewne czyszczenie przed zamknięciem aplikacji, ale o ile mogę stwierdzić, nie możesz, z aplikacji konsoli, zmusić aplikacji do kontynuowania działania, jeśli nie obsłużysz wyjątku w wątku, z którego jest wyrzucany bez użycia niejasnych opcji zgodności, aby aplikacja działała tak, jak w przypadku platformy .NET 1.x. Ten kod pokazuje, w jaki sposób główny wątek może być powiadamiany o wyjątkach pochodzących z innych wątków, ale nadal niefortunnie kończy się:
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;
}
}
Moim zdaniem najczystszym sposobem obsługi tego w aplikacji konsolowej jest upewnienie się, że każdy wątek ma moduł obsługi wyjątków na poziomie głównym:
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");
}
}
Console.ReadLine()
zakłóceń lub innych zakłóceń w przebiegu programu. Ale dostaję wyjątek ponownie zgłaszany raz po raz)