2016-06-14 23 views
5

Sto cercando di capire perché la mia app per console non viene abbattuta da un'eccezione di attività non gestita. Tutto ciò che faccio è creare un'attività in cui lancio immediatamente un'eccezione. Finalmente costringo GC. Nel primo esempio ho un gestore per l'evento TaskScheduler.UnobservedTaskException e posso vedere che l'eccezione viene gestita.Applicazione console non eliminata da un'eccezione di attività non gestita

static async Task ThrowsException() 
{ 
    Console.WriteLine("Throwing!"); 
    throw new Exception("Test exception"); 
} 

static void Main(string[] args) 
{ 
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 
    ThrowsException(); 
    Console.WriteLine("Collecting garbage."); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    Console.WriteLine("Done collecting garbage."); 
    Console.ReadKey(); 
} 

static void TaskScheduler_UnobservedTaskException(object sender, 
    UnobservedTaskExceptionEventArgs e) 
{ 
    Console.WriteLine("Unobserved task exception occured in finalizer."); 
    Console.WriteLine(e.Exception.InnerException.Message); 
} 

uscita:

Throwing! 
Collecting garbage. 
Unobserved task exception occured in finalizer. 
Test exception 
Done collecting garbage. 

Ma se io commento la linea TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException il programma viene eseguito ancora a compimento. In questo caso l'output è:

Throwing! 
Collecting garbage. 
Done collecting garbage. 

Perché non fa il crash dell'applicazione in questo caso?

risposta

4

Non arrestare il programma da un'eccezione di operazione non osservata era una modifica apportata per .NET 4.5, vedere remarks section of the MSDN for the event. Se si desidera che il programma per avere il pre comportamento .NET 4.5 e causare il crash è necessario mettere nel vostro app.config

<configuration> 
    <runtime> 
     <ThrowUnobservedTaskExceptions enabled="true"/> 
    </runtime> 
</configuration> 

Questo porterà indietro il vecchio comportamento.

0

ThrowsException è un metodo asincrono e pertanto, a meno che non si attenda con questo metodo, l'eccezione verrà inghiottita.
Presumo che è necessario chiamare questo metodo come questo:

ThrowsException.Wait(); 

O anche intercettare l'eccezione:

try 
{ 
    ThrowsException().Wait(); 
} 
catch (AggregateException e) 
{ 
    // Do something 
} 

Inoltre, la lettura del seguente vi aiuterà a capire il motivo per cui non è precipitato il tuo applicazione: TaskScheduler.UnobservedTaskException Event.