Se si dispone di un'applicazione a thread singolo, è possibile utilizzare un semplice try/catch nella funzione Main, tuttavia, questo non copre le eccezioni che possono essere generate all'esterno della funzione Main, su altri thread, ad esempio (come notato in altri commenti).Questo codice dimostra come un'eccezione può causare la chiusura dell'applicazione anche se si è tentato di gestirla in Main (notare come il programma si chiude con grazia se si preme enter e si consente all'applicazione di uscire con garbo prima che si verifichi l'eccezione, ma se si lascia che si esegua , termina piuttosto infelice):
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;
}
}
è possibile ricevere la notifica di quando un altro thread genera un'eccezione per eseguire alcuni pulire prima alla chiusura dell'applicazione, ma per quanto ne so, non si può, da un'applicazione console , forzare l'applicazione a continuare a funzionare se non si gestisce l'eccezione sul thread da cui viene generata senza utilizzare alcune opzioni di compatibilità oscure per far sì che l'applicazione si comporti come con .NET 1.x. Questo codice illustra come il filo conduttore può essere notificato di eccezioni provenienti da altri thread, ma sarà comunque terminerà infelice:
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;
}
}
Quindi, a mio parere, il modo più pulito di gestire la cosa in un'applicazione console è quello di garantire che ogni thread ha un gestore di eccezioni al livello principale:
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, stupido errore, ho bisogno di aggiungere AddHandler davanti AppDomain.CurrentDomain di vedere "UnhandledException" in VB.NET ... –
ho implementato cosa hai proposto qui, ma non voglio uscire dall'applicazione. Voglio solo loggarlo e continuare il processo (senza 'Console.ReadLine()' o qualsiasi altro disturbo del flusso del programma, ma quello che ottengo è l'eccezione che si ripropone ancora e ancora, e ancora .. –
@Shahrooz Jefri: Non è possibile continuare una volta ottenuta un'eccezione non gestita Lo stack è incasinato, e questo è terminale.Se si dispone di un server, ciò che è possibile fare in UnhandledExceptionTrapper è riavviare il programma con gli stessi argomenti della riga di comando. –