Ik heb een vrij ingewikkelde WPF applicatie waarbij het zo nu en dan voorkomt dat er iets mis gaat wat een unhandled exception als gevolg heeft. Ik gebruik de AppDomain.CurrentDomain.UnhandledException event om dit soort exceptions toch te kunnen loggen voordat ik de applicatie afsluit.
Een test situatie:
Als ik in MainWindow.RunTest een simpele exception gooi dan gaat alles goed, de exception word gelogd en de applicatie sluit netjes af (eventueel kan ik zelf een message dialog tonen aan de user).
Echter, als er een exception voorkomt in een thread, dan gaat dit niet helemaal goed.
Als ik dit draai dan wordt de exception wel gelogd, maar daarna sluit de applicatie niet "netjes" af. De boel lijkt nog steeds te crashen met een windows popup "TestApplication has stopped working" als gevolg.
Dit is een probleem omdat deze applicatie vaak in de achtergrond zal draaien terwijl de user een spel aan het spelen is. In sommige situaties (Windows 10 vooral) zal deze popup de user uit het spel halen (spel naar de achtergrond) en dat is enorm storend (het gaat om een race simulator waarbij je race gewoon voorbij is als dit gebeurt).
Hoe kan ik voorkomen dat de applicatie alsnog crasht? Het is prima dat de applicatie afsluit, maar graag zonder popup...
Een "oplossing" die ik heb gevonden is gebruik van de volgende setting in de config:
Als ik dit gebruik is het gedrag een beetje vreemd. De applicatie lijkt nu niet meer te crashen, echter blijft alles zelfs draaien. De 'Shutdown' wordt blijkbaar niet uitgevoerd. Dit is ook niet helemaal de bedoeling, als er zo'n unhandled exception optreedt kan ik natuurlijk niet garanderen dat alles nog lekker loopt dus is het beste om de boel maar af te sluiten.
Vreemd genoeg lijkt de code na de exception handling wel nog gewoon uitgevoerd - ik zie wel de messagebox met "Exception". Dit is een beetje lastig te debuggen want in de debugger komt de code nooit zover en blijft hij op de exception terug komen. Als ik de exe zonder debugger uitvoer echter dan wordt de messagebox gewoon getoond, maar de applicatie sluit niet af.
Verder vind ik ook hier en daar mensen die sterk afraden deze setting te gebruiken. Zijn er betere oplossingen?
Een test situatie:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // Handle exceptions AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; // Create test window var w = new MainWindow(); w.Show(); // Run test method that throws exception w.RunTest(); } private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) { // Log exception var ex = (Exception)e.ExceptionObject; HandleException("Unhandled exception (domain).", ex); MessageBox.Show("Exception"); // Shutdown Shutdown(1); } public void HandleException(string action, Exception ex) { //... Logging } } |
Als ik in MainWindow.RunTest een simpele exception gooi dan gaat alles goed, de exception word gelogd en de applicatie sluit netjes af (eventueel kan ik zelf een message dialog tonen aan de user).
Echter, als er een exception voorkomt in een thread, dan gaat dit niet helemaal goed.
C#:
1
2
3
4
5
6
7
8
9
10
| public void RunTest() { var t = new Thread(T); t.Start(); } private void T() { throw new Exception("1"); } |
Als ik dit draai dan wordt de exception wel gelogd, maar daarna sluit de applicatie niet "netjes" af. De boel lijkt nog steeds te crashen met een windows popup "TestApplication has stopped working" als gevolg.
Dit is een probleem omdat deze applicatie vaak in de achtergrond zal draaien terwijl de user een spel aan het spelen is. In sommige situaties (Windows 10 vooral) zal deze popup de user uit het spel halen (spel naar de achtergrond) en dat is enorm storend (het gaat om een race simulator waarbij je race gewoon voorbij is als dit gebeurt).
Hoe kan ik voorkomen dat de applicatie alsnog crasht? Het is prima dat de applicatie afsluit, maar graag zonder popup...
Een "oplossing" die ik heb gevonden is gebruik van de volgende setting in de config:
XML:
1
2
3
| <runtime> <legacyUnhandledExceptionPolicy enabled="1"/> </runtime> |
Als ik dit gebruik is het gedrag een beetje vreemd. De applicatie lijkt nu niet meer te crashen, echter blijft alles zelfs draaien. De 'Shutdown' wordt blijkbaar niet uitgevoerd. Dit is ook niet helemaal de bedoeling, als er zo'n unhandled exception optreedt kan ik natuurlijk niet garanderen dat alles nog lekker loopt dus is het beste om de boel maar af te sluiten.
Vreemd genoeg lijkt de code na de exception handling wel nog gewoon uitgevoerd - ik zie wel de messagebox met "Exception". Dit is een beetje lastig te debuggen want in de debugger komt de code nooit zover en blijft hij op de exception terug komen. Als ik de exe zonder debugger uitvoer echter dan wordt de messagebox gewoon getoond, maar de applicatie sluit niet af.
Verder vind ik ook hier en daar mensen die sterk afraden deze setting te gebruiken. Zijn er betere oplossingen?