We know that we can add a when
keyword after a catch
filter. But if there is another exception happened in the when
expression, the app will totally crash.
This happens in .NET Framework 4.8 but in .NET Core 3.0, it works correctly as the document says.
Maybe this is a bug in the .NET Framework 4.8 CLR.
本文使用 多种语言 编写,请选择你想阅读的语言:
中文 English
The when
in the official document
You can view the official document here:
- Using User-Filtered Exception Handlers - Microsoft Docs
There is such a sentence here:
The expression of the user-filtered clause is not restricted in any way. If an exception occurs during execution of the user-filtered expression, that exception is discarded and the filter expression is considered to have evaluated to false. In this case, the common language runtime continues the search for a handler for the current exception.
When there is an exception occurred in the when expression the exception will be ignored and the expression will return false.
A demo
We can write a demo to verify this behavior of the official document.
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 | using System; using System.IO; namespace Walterlv.Demo.CatchWhenCrash { internal class Program { private static void Main(string[] args) { try { try { Console.WriteLine("Try"); throw new FileNotFoundException(); } catch (FileNotFoundException ex) when (ex.FileName.EndsWith(".png")) { Console.WriteLine("Catch 1"); } catch (FileNotFoundException) { Console.WriteLine("Catch 2"); } } catch (Exception) { Console.WriteLine("Catch 3"); } Console.WriteLine("End"); } } } |
---|
Obviously, the FileName
property will keep null
in the first when expression and will cause a NullReferenceException
. It is not recommended to write such the code but it can help us verify the behavior of the catch
-when
blocks.
If the official document is correct then we can get the output as Try
-Catch 2
-End
because the exception in the when
will be ignored and the outer catch
will not catch it and then the when
expression returns false so that the exception handling goes into the second one.
In .NET Core 3.0 and in .NET Framework 4.8
The pictures below show the actual output of the demo code above in .NET Core 3.0 and in .NET Framework 4.8.
Only in the .NET Core 3.0, the output behaves the same as the official document says. But in .NET Framework 4.8, the End
even not appear in the output. We can definitely sure that the app crashes in .NET Framework 4.8.
If we run the app step by step in Visual Studio, we can see that a CLR exception happens.
This animated picture below shows how the code goes step by step.
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/try-catch-when-causes-app-crash-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。