当前位置: 首页 > news >正文

.NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃

在 .NET Framework 4.8 中,try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃。而 .NET Core 3.0 中不会出现这样的问题。

本文可能是正在像微软报告的一个 Bug。


本文由多种语言编写而成,请选择你喜欢的语言:

  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃 - walterlv
  • App will crash when using the when keyword in a catch expression - walterlv

本文内容

    • 官方文档中 when 的行为
    • 示例程序
    • 在 .NET Core 3.0 中的行为和 .NET Framework 4.8 中的行为

官方文档中 when 的行为

你可以前往官方文档:

  • 使用用户筛选的异常处理程序 - Microsoft Docs

在其中,你可以找到这样一段话:

用户筛选的子句的表达式不受任何限制。 如果在执行用户筛选的表达式期间发生异常,则将放弃该异常,并视筛选表达式的值为 false。 在这种情况下,公共语言运行时继续搜索当前异常的处理程序。

即当 when 块中出现异常时,when 表达式将视为值为 false,并且此异常将被忽略。

示例程序

鉴于官方文档中的描述,我们可以编写一些示例程序来验证这样的行为。

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");
        }
    }
}

很显然,我们直接 new 出来的 FileNotFoundExceptionFileName 属性会保持为 null。对其解引用会产生 NullReferenceException。很显然代码不应该这么写,但可以用来验证 catch-when 语句的行为。

按照官网描述,输出应该为 Try-Catch 2-End。因为 when 中的异常被忽略,因此不会进入到外层的 catch 块中;因为 when 中出现异常导致表达式值视为 false,因此进入了更合适的异常处理块 Catch 2 中。

在 .NET Core 3.0 中的行为和 .NET Framework 4.8 中的行为

下面两张图分别是这段代码在 .NET Core 3.0 和 .NET Framework 4.8 中的输出:

.NET Core 3.0 中的行为

.NET Framework 4.8 中的行为

可以注意到,只有 .NET Core 3.0 中的行为符合官方文档的描述,而 .NET Framework 4.8 中甚至连 End 都没有输出!几乎可以确定,程序在 .NET Framework 4.8 中出现了致命的崩溃!

如果我们以 Visual Studio 调试启动此程序,可以看到抛出了 CLR 异常:

抛出了 CLR 异常

以下是在 Visual Studio 中单步跟踪的步骤:

单步调试


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

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

相关文章:

  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • 如何给 Windows Terminal 增加一个新的终端(以 Bash 为例)
  • 在 Visual Studio 中设置当发生某个特定异常或所有异常时中断
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • 如何在 Windows 10 中安装 WSL2 的 Linux 子系统
  • 如何安装和准备 Visual Studio 扩展/插件开发环境
  • 基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NET/C# 源代码分析器 Analyzer 和修改器 CodeFixProvider
  • 软件界面中一些易混淆/易用错的界面文案,以及一些约定俗成的文案约定
  • WPF 的 VisualBrush 只刷新显示的视觉效果,不刷新布局范围
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • 使用 Roslyn 分析代码注释,给 TODO 类型的注释添加负责人、截止日期和 issue 链接跟踪
  • 为 NuGet 指定检测的 MSBuild 路径或版本,解决 MSBuild auto-detection: using msbuild version 自动查找路径不合适的问题
  • 解决方案文件 sln 中的项目类型 GUID
  • 两种方法设置 .NET/C# 项目的编译顺序,而不影响项目之间的引用
  • 理解 Visual Studio 解决方案文件格式(.sln)
  • 「面试题」如何实现一个圣杯布局?
  • Angular 2 DI - IoC DI - 1
  • Date型的使用
  • echarts花样作死的坑
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • iOS | NSProxy
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • nginx 配置多 域名 + 多 https
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Vultr 教程目录
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 百度地图API标注+时间轴组件
  • 第十八天-企业应用架构模式-基本模式
  • 浮动相关
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 排序算法之--选择排序
  • 如何实现 font-size 的响应式
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 微信小程序:实现悬浮返回和分享按钮
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (2)(2.10) LTM telemetry
  • (6)STL算法之转换
  • (8)STL算法之替换
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (poj1.2.1)1970(筛选法模拟)
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (翻译)terry crowley: 写给程序员
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (六)c52学习之旅-独立按键
  • (四)c52学习之旅-流水LED灯
  • ***检测工具之RKHunter AIDE
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET delegate 委托 、 Event 事件,接口回调
  • /etc/sudoers (root权限管理)