2

C#での「使用」ブロックの操作に慣れようとしていますが、いつ使用すべきかを理解するのに苦労しています。

ここに例があります。

usingブロックなしの私の元のコード:

SqlConnection conn = new SqlConnection(cCon.getConn());
    SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new SqlParameter("@x", xxx));
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        
    try
    {
        conn.Open();
        cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    { }
    finally
    {
        conn.Close();
    }

しかし、私は本当にこれを行うべきですか?または私は使用する必要があり(SqlConnection conn = new SqlConnection(cCon.getConn()))ますか?私がこれを理解するのを手伝ってください。私が最初にそれをやっている方法はとても間違っていますか?

SqlConnection conn = new SqlConnection(cCon.getConn());
   using( SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new SqlParameter("@x", xxx));
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        
    try
    {
        conn.Open();
        cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    { }
    finally
    {
        conn.Close();
    }
}
4

5 に答える 5

10

しかし、私はそれらをいつ使うべきか理解するのに苦労しています。

それは簡単です。IDisposableインターフェースを実装するクラスを扱うときはいつでも、それらを使用する必要があります。ちょうどこのような:

using (SqlConnection conn = new SqlConnection(cCon.getConn()))
using (SqlCommand cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "sp_SaveSomething";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new SqlParameter("@x", xxx));
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        
    cmd.ExecuteNonQuery();
}

また、いくつかの例外を処理したい場合は、処理したいコードをtry/catchステートメントでラップできます。

try
{
    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    using (SqlCommand cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "sp_SaveSomething";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@x", xxx));
        cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        
        cmd.ExecuteNonQuery();
    }
}
catch (Exception ex)
{
    // do something here with the exception, don't just consume it,
    // otherwise it's meaningless to catch it
}

ご覧のとおり、すべてのIDisposableリソース(このコードスニペットではSqlConnectionとSqlCommand)がusing ステートメントで適切にラップされ、例外がスローされた場合でも適切に破棄されることが保証されます。結果として、finallyステートメントを使用して明示的にこれを行う必要がなくなります。

また、ADO.NETは、SqlConnectionconnection poolでメソッドを呼び出すときに、データベースへの物理接続を開いていないという意味を使用していることを忘れないでください。.Open()あなたは単にプールから1つを引いています。また、.Close(または.Dispose)メソッドを呼び出すときは、接続を閉じていません。再利用できるように、接続プールに戻すだけです。

于 2013-03-26T14:15:19.933 に答える
0

ブロックを使用する場合は、接続を閉じる必要はありません。使用ブロックは、IDisposableを実装するオブジェクトに使用されます。IDisposableを使用すると、オブジェクトは、GCによって収集される前に管理されていないリソースをクリアできます。これによりメモリが解放され、GCがそのオブジェクトを収集できるようになります。

于 2013-03-26T14:16:15.807 に答える
0

usingブロックは、使い捨てオブジェクトを自動的に閉じて破棄するtry/finally句です。内部のtry/catchを追加すると、スローされた例外を何らかの方法で処理する場合にのみ機能します。あなたの例では、catchブロックでは何もしないので、不要です。

SqlCommandとSqlConnectionはどちらも使い捨てなので、コードを次のように変更する必要があります。

using(SqlConnection conn = new SqlConnection(cCon.getConn())
using( SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new SqlParameter("@x", xxx));
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        
    conn.Open();
    cmd.ExecuteNonQuery();
}
于 2013-03-26T14:16:26.657 に答える
0

SqlConnectionSqlCommand両方がを実装しているので、実際には、ここでいくつかの使用ブロックが必要ですIDisposable。また、using最後に接続を閉じる処理も行うため、明示的なものconn.Close();は不要になります。

    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    using (SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@x", xxx));
        cmd.Parameters.Add(new SqlParameter("@ORG", ORG));
        try
        {
            conn.Open();
            cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            // Log error, etc.
        }
    }
于 2013-03-26T14:16:46.607 に答える
0

それはこのようになります:

using (SqlConnection conn = new SqlConnection(cCon.getConn()))
{
    using (SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn))
    {
        conn.Open();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@x", xxx));
        cmd.Parameters.Add(new SqlParameter("@ORG", ORG));        

        cmd.ExecuteNonQuery();
    }
}

インターフェイスSqlConnectionSqlCommand実装すると、ブロックはメソッドとメソッドを処理します。IDisposableusingCloseDispose

于 2013-03-26T14:17:45.800 に答える