.NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)

本文探讨了.NET/C#编程中一种不常见的异常处理技巧,即使用空的try块配合finally块。这样做是为了确保在finally块中的代码在任何情况下都能执行,不受线程中断或内存异常的影响。受约束的执行区域(Constrained Execution Regions, CER)是这种策略的基础,它允许JIT编译器预先准备finally块的代码,以保证关键操作的可靠性。" 135113081,10097137,米家APP设备所有权转让步骤,"['智能家居', '米家app', 'HA', '设备管理', '家庭自动化']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不知你是否见过 try { } finally { } 代码中,try 块留空,而只往 finally 中写代码的情况呢?这种写法有其特殊的目的。

本文就来说说这种不一样的写法。


空的 try 块

你可以点开这个链接查看 Exception 类,在里面你可以看到一段异常处理的代码非常奇怪:

// 代码已经过简化。
internal void RestoreExceptionDispatchInfo(ExceptionDispatchInfo exceptionDispatchInfo)
{
   
   
    // 省略代码。
    try{
   
   }
    finally
    {
   
   
        // 省略代码。
    }
    // 省略代码。
}

神奇之处就在于,其 try 块是空的,重要代码都放在 finally 中。那为什么会这么写呢?

在代码注释中的解释为:

We do this inside a finally clause to ensure ThreadAbort cannot be injected while we have taken the lock. This is to prevent unrelated exception restorations from getting blocked due to TAE.

翻译过来是:

finally 子句中执行此操作以确保在获取锁时无法注入 ThreadAbort。这是为了防止不相关的异常恢复因 TAE 而被阻止。

也就是说,此方法是为了与 Thread.Abort 对抗,防止 Thread.Abort 中断此处代码的执行。 Thread.Abort 的执行交给 CLR 管理,finally 的执行也是交给 CLR 管理。CLR 确保 finally 块执行的时候不会被 Thread.Abort 阻止。

代码在 .NET Core 和 .NET Framework 中的实现完全一样:

// This is invoked by ExceptionDispatchInfo.Throw to restore the exception stack trace, corresponding to the original throw of the
// exception, just before the exception is "rethrown".
[
<think>题目要求一个简化版的学生管理系统的前端代码。但是注意,我们之前约定只提供Java代码,而前端通常使用HTML/CSS/JavaScript。然而,题目要求“你提供的代码只能是Java代码”,这里可能存在矛盾。考虑到题目要求,可能有以下两种理解:1.题目要求的是基于Java的前端技术(如JavaFX、Swing等)来编前端。2.题目描述有误,但我们必须遵守规则只提供Java代码。由于题目明确要求“学生管理系统(简化版)”,并且要求前端代码,但只能使用Java,因此我们选择使用Java的图形用户界面库来实现,比如Swing或JavaFX。这里我们选择使用Swing来构建一个非常简化的学生管理系统前端界面,因为Swing是Java标准库的一部分,无需额外依赖。功能要求(简化版):1.能够添加学生信息(学号、姓名、年龄)2.能够显示学生列表3.能够删除学生(通过选择)我们将实现以下组件: -一个窗口(JFrame) -输入字段:学号(JTextField)、姓名(JTextField)、年龄(JTextField) -添加按钮(JButton) -学生列表(JTable)显示-删除按钮(JButton)用于删除选中的学生注意:为了简化,我们不使用数据库,数据保存在内存中(使用List)。步骤:1.创建学生类(Student)2.创建GUI界面,并添加组件3.实现添加学生的事件处理4.实现删除学生的事件处理5.使用表格模型(DefaultTableModel)来管理表格数据代码结构:我们将在一个类中实现,但为了清晰,会分开定义学生类和主界面类。由于题目要求只提供Java代码,我们将编完整的Java代码。</think>### 学生管理系统(简化版)前端实现(使用JavaFX) 以下是一个基于JavaFX的简化版学生管理系统前端实现。这个系统包含学生信息的添加、显示和删除功能,采用MVC架构设计。 ```java import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.*; import javafx.stage.Stage; public class StudentManagementSystem extends Application { // 学生模型类 public static class Student { private final String id; private final String name; private final int age; private final String major; public Student(String id, String name, int age, String major) { this.id = id; this.name = name; this.age = age; this.major = major; } // Getters public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public String getMajor() { return major; } } // UI组件 private final ObservableList<Student> studentList = FXCollections.observableArrayList(); private TableView<Student> tableView; private TextField idField, nameField, ageField, majorField; @Override public void start(Stage primaryStage) { // 创建主布局 BorderPane root = new BorderPane(); root.setPadding(new Insets(15)); // 创建顶部输入表单 GridPane form = createInputForm(); root.setTop(form); // 创建中间表格 tableView = createStudentTable(); root.setCenter(tableView); // 创建底部按钮区域 HBox buttonBox = createButtonBar(); root.setBottom(buttonBox); // 设置场景和舞台 Scene scene = new Scene(root, 700, 500); primaryStage.setTitle("学生管理系统"); primaryStage.setScene(scene); primaryStage.show(); } // 创建输入表单 private GridPane createInputForm() { GridPane grid = new GridPane(); grid.setHgap(10); grid.setVgap(10); grid.setPadding(new Insets(10)); grid.setStyle("-fx-background-color: #f0f0f0;"); // 表单标签 Label idLabel = new Label("学号:"); Label nameLabel = new Label("姓名:"); Label ageLabel = new Label("年龄:"); Label majorLabel = new Label("专业:"); // 输入字段 idField = new TextField(); nameField = new TextField(); ageField = new TextField(); majorField = new TextField(); // 添加到网格 grid.add(idLabel, 0, 0); grid.add(idField, 1, 0); grid.add(nameLabel, 0, 1); grid.add(nameField, 1, 1); grid.add(ageLabel, 0, 2); grid.add(ageField, 1, 2); grid.add(majorLabel, 0, 3); grid.add(majorField, 1, 3); return grid; } // 创建学生表格 private TableView<Student> createStudentTable() { TableView<Student> table = new TableView<>(); table.setItems(studentList); // 学号列 TableColumn<Student, String> idCol = new TableColumn<>("学号"); idCol.setCellValueFactory(new PropertyValueFactory<>("id")); // 姓名列 TableColumn<Student, String> nameCol = new TableColumn<>("姓名"); nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); // 年龄列 TableColumn<Student, Integer> ageCol = new TableColumn<>("年龄"); ageCol.setCellValueFactory(new PropertyValueFactory<>("age")); // 专业列 TableColumn<Student, String> majorCol = new TableColumn<>("专业"); majorCol.setCellValueFactory(new PropertyValueFactory<>("major")); table.getColumns().addAll(idCol, nameCol, ageCol, majorCol); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); return table; } // 创建按钮栏 private HBox createButtonBar() { HBox hbox = new HBox(15); hbox.setPadding(new Insets(15)); hbox.setStyle("-fx-background-color: #e0e0e0;"); // 添加按钮 Button addButton = new Button("添加学生"); addButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white;"); addButton.setOnAction(e -> addStudent()); // 删除按钮 Button deleteButton = new Button("删除学生"); deleteButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white;"); deleteButton.setOnAction(e -> deleteStudent()); // 清除按钮 Button clearButton = new Button("清除表单"); clearButton.setOnAction(e -> clearForm()); hbox.getChildren().addAll(addButton, deleteButton, clearButton); return hbox; } // 添加学生 private void addStudent() { try { String id = idField.getText(); String name = nameField.getText(); int age = Integer.parseInt(ageField.getText()); String major = majorField.getText(); if (id.isEmpty() || name.isEmpty() || major.isEmpty()) { showAlert("输入错误", "所有字段都必须填!"); return; } studentList.add(new Student(id, name, age, major)); clearForm(); } catch (NumberFormatException e) { showAlert("输入错误", "年龄必须是有效的数字!"); } } // 删除学生 private void deleteStudent() { Student selected = tableView.getSelectionModel().getSelectedItem(); if (selected != null) { studentList.remove(selected); } else { showAlert("删除错误", "请先选择一个学生!"); } } // 清除表单 private void clearForm() { idField.clear(); nameField.clear(); ageField.clear(); majorField.clear(); } // 显示警告对话框 private void showAlert(String title, String message) { Alert alert = new Alert(Alert.AlertType.WARNING); alert.setTitle(title); alert.setHeaderText(null); alert.setContentText(message); alert.showAndWait(); } public static void main(String[] args) { launch(args); } } ``` ### 系统功能说明 1. **学生信息管理**: - 添加学生:填学号、姓名、年龄和专业 - 删除学生:从表格中选择学生后删除 - 显示学生:表格形式展示所有学生信息 2. **UI设计**: - 顶部:输入表单(学号、姓名、年龄、专业) - 中部:表格展示学生信息 - 底部:操作按钮(添加、删除、清除) 3. **数据验证**: - 确保所有字段都已填 - 验证年龄字段为有效数字 - 删除前需选择学生 4. **用户体验**: - 表单提交后自动清除 - 错误提示对话框 - 彩色按钮区分操作类型 ### 运行说明 1. 确保已安装Java 8或更高版本 2. 编译运行程序: ```bash javac StudentManagementSystem.java java StudentManagementSystem ``` 3. 系统界面将显示,可进行学生管理操作 ### 界面效果预览 - 顶部:浅灰色背景的表单区域 - 中部:带有四列(学号、姓名、年龄、专业)的表格 - 底部:绿色添加按钮、红色删除按钮和普通清除按钮
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值