C# using statement catch error

后端 未结 16 1306
轻奢々
轻奢々 2021-01-30 14:06

I am just looking at the using statement, I have always known what it does but until now not tried using it, I have come up with the below code:

 using (SqlComma         


        
16条回答
  •  迷失自我
    2021-01-30 14:44

    When doing IO work I code to expect an exception.

    SqlConnection conn = null;
    SqlCommand cmd = null;
    
    try
    {
        conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)
        cmd = new SqlCommand(reportDataSource, conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
        cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
        cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;
    
            conn.Open(); //opens connection
    
        DataSet dset = new DataSet();
        new SqlDataAdapter(cmd).Fill(dset);
        this.gridDataSource.DataSource = dset.Tables[0];
    }
    catch(Exception ex)
    {
        Logger.Log(ex);
        throw;
    }
    finally
    {
        if(conn != null)
            conn.Dispose();
    
            if(cmd != null)
            cmd.Dispose();
    }
    

    Edit: To be explicit, I avoid the using block here because I believe it to be important to log in situations like this. Experience has taught me that you never know what kind of weird exception might pop up. Logging in this situation might help you detect a deadlock, or find where a schema change is impacting a little used and little tested part of you code base, or any number of other problems.

    Edit 2: One can argue that a using block could wrap a try/catch in this situation, and this is completely valid and functionally equivalent. This really boils down to preference. Do you want to avoid the extra nesting at the cost of handling your own disposal? Or do you incur the extra nesting to have auto-disposal. I feel that the former is cleaner so I do it that way. However, I don't rewrite the latter if I find it in the code base in which I am working.

    Edit 3: I really, really wish MS had created a more explicit version of using() that made it more intuitive what was really happening and given more flexibility in this case. Consider the following, imaginary code:

    SqlConnection conn = null;
    SqlCommand cmd = null;
    
    using(conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString),
              cmd = new SqlCommand(reportDataSource, conn)
    {
        conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString);
        cmd = new SqlCommand(reportDataSource, conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
        cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
        cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;
            cmd.Open();
    
        DataSet dset = new DataSet();
        new SqlDataAdapter(cmd).Fill(dset);
        this.gridDataSource.DataSource = dset.Tables[0];
    }
    catch(Exception ex)
    {
        Logger.Log(ex);
        throw;
    }
    

    A using statement just creates a try/finally with Dispose() calls in the finally. Why not give the developer a unified way of doing disposal and exception handling?

提交回复
热议问题