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.


本文使用 多种语言 编写,请选择你想阅读的语言:

The when in the official document

You can view the official document here:

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.

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.

.NET Core 3.0

.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.

CLR error

This animated picture below shows how the code goes step by step.

Step debugging


本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/try-catch-when-causes-app-crash-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 dotnet 职业技术学院 (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系