try语句未执行-直接捕获

时间:2019-11-14 01:52:36

标签: c# winforms exception try-catch

我正在设置一个winform,它将一个学生的名字,姓氏和学生ID放入一个名为sql的{​​{1}}数据库中,并执行一个存储过程来搜索对于该学生,然后在按下搜索按钮时在college中显示结果。每当我按下搜索按钮时,都会出现以下错误

  

“ Search2.exe中出现类型'System.TypeInitializationException'的第一次机会异常”。

我的程序正在跳过显示的DataGridView块,并转到Try语句。谁能告诉我为什么?

Catch
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Search2
{
    public partial class frmSearch : Form
    {
        public frmSearch()
        {
            InitializeComponent();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            string studid, fname, lname;

            try
            {
                // get the values
                fname = txtFname.Text.Trim();
                lname = TxtLname.Text.Trim();
                studid = txtStudentID.Text.Trim();

                //instantiate datatier
                Class1 astudent = new Class1();
                DataSet ds = new DataSet();

                ds = astudent.GetStudents(studid, fname, lname);

                // populate the datagrid with dataset
                dgvStudents.DataSource = ds.Tables[0];
            }
            catch (Exception ex)
            {

            }
        }

        private void frmSearch_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'collegeDataSet.STUDENT' table. You can move, or remove it, as needed.
            //this.sTUDENTTableAdapter.Fill(this.collegeDataSet.STUDENT);

        }
    }
}

2 个答案:

答案 0 :(得分:3)

根据异常类型进行判断-TypeInitializationException-我怀疑问题出在静态字段初始值设定项上:

static String connString = ConfigurationManager.ConnectionStrings["Data Source=EVEDELL17;Initial Catalog=College;Integrated Security=True"].ConnectionString;
static SqlConnection myConn = new SqlConnection(connString);
static System.Data.SqlClient.SqlCommand cmdString = new System.Data.SqlClient.SqlCommand();

那些初始化程序将在运行时第一次“触摸”其包含的类(Class1)时运行。因为它们不在方法中,所以当它们失败时,编译器很难给出有用的堆栈跟踪。尝试用静态构造函数替换内联初始化程序:

static String connString;
static SqlConnection myConn;
static System.Data.SqlClient.SqlCommand cmdString;

static Class1() {
    connString = ConfigurationManager.ConnectionStrings["Data Source=EVEDELL17;Initial Catalog=College;Integrated Security=True"].ConnectionString;
    myConn = new SqlConnection(connString);
    cmdString = new System.Data.SqlClient.SqlCommand();
}

我认为您将通过这种方式获得更好的错误消息。您还可以在构造函数中设置一个断点,以查看初始化期间发生的确切情况。

在此处了解更多信息:https://docs.microsoft.com/en-us/dotnet/api/system.typeinitializationexception?view=netframework-4.8#Static

答案 1 :(得分:0)

Xander得到了我认为的答案:初始化这些静态字段时,某些东西“碰撞”。众所周知,静态/类型构造函数在传达异常方面很差:

https://docs.microsoft.com/en-us/dotnet/api/system.typeinitializationexception

但是,潜在的问题是模式之一。并且有几个问题。但是,您经常可以捏造这些部分以获取简单的学习示例。

一次性

SqlConnectons是Disposeable,因为它包含一些非托管资源。始终丢弃可丢弃物。我的个人规则是:

  • 永远不要拆分Disposeable资源的创建和处置。创建,使用,处置。全部都在同一段代码中-理想情况下使用using statement/block
  • 一个罕见的例外是,如果您包装了一些您无法处置的可处置物品(甚至可能偶尔使用)。在那种情况下,您自己可以使Dispose模式生效,其唯一目的是中继Dispose()调用。 (因此,所有类中约有95%只能是Disposable)。

避免使用Globals / Static

静态变量是全局变量。在发明了这些之后,我们很快意识到使用其中一种是90%的可怕想法。 特别用于交换/共享数据。

尽管我走得更远,但从来没有一个静态字段可以写。 constantreadonly(运行时常量)应该是您曾经使用过的唯一静态变量。如果无法做到这一点,请不要使其静态。诸如连接字符串之类的东西在该规则上得到提升。如果您不能像这样标记它,请不要让它以静态开头

在顶部,我创建一个类,结构或tupple。并将其实例分配给静态的readonly / constant变量。诸如连接字符串之类的东西既可以是实例变量,也可以在每次调用GetStudents之类的函数时上交。实际上,Class1看起来很像数据库访问抽象。尤其是那些属于“请勿静态”规则的人。