3

SqlConnectionと をSqlCommand実装するので、それらをステートメントIDisposableでラップしています。using

ただし、メソッドでそれらを作成してからusingステートメントに渡すため、メソッドによって作成されたものを閉じるブレースが破棄するかどうかを知りたいとusing思いSqlCommandました。

だから私はこれを試しました:

private void button1_Click(object sender, EventArgs e)
{
    SqlCommand command = new SqlCommand();
    command.CommandTimeout = 10;
    command.Disposed += s_Disposed;    
    using (SqlCommand tempCommand = command) { }//This is where even "command" is supposed to get disposed.
    Text = command.CommandTimeout.ToString();
}

void s_Disposed(object sender, EventArgs e)
{
    MessageBox.Show("Disposed");
}

MessageBoxそして、廃棄を暗示する do が表示されたのを見て驚いたが、Text は "10" だった。

なんで?

4

2 に答える 2

3

一般に、実装するオブジェクトIDisposable(たとえば、SqlConnection)は、ユニバースのどこか(SQLサーバーなど)で何かを実行するように要求され(たとえば、接続を開いて維持する)、指示があるまで実行し続けるために実行します。 。一般に、IDisposableオブジェクトは、受信することを期待する要求を尊重する場合(たとえば、SQL操作を実行する場合)、オブジェクトに代わってそれらの外部のものを動作させる必要があります。目的はDispose、呼び出されたオブジェクトを実際に破棄することではなく、他の誰もそれを必要としないため、代わりに何かをしている外部エンティティにそれらを知らせる必要があることをオブジェクトに知らせることです。もはやそうする必要はありません(例えば、誰も尋ねないので)SqlConnectionこれ以上リクエストを実行するために、サーバーが接続を開いたままにする必要はなくなりました)。

オブジェクトに対して呼び出された後、Dispose利用できなくなった外部エンティティの支援を必要とする何かを行うように求められた場合、アクションが他の方法で失敗するよりもObjectDisposedException、オブジェクトがそれ自体をスローする方が適切です。 。一方、オブジェクトが外部エンティティを使用せずに完全にうまく実行できることを実行するように求められた場合、それが適切であることがよくあります。オブジェクトを使用するコードは、通常、使用可能であると明示的に文書化されていないメンバーの使用を控え、その後も有用なメンバーであると想定することを避ける必要があります。IDisposableDisposeDisposeクラスの1つのバージョンでは、常にそうします。それでも、多くの場合、クラスでは、特定のメンバーを使用Disposeできないようにするよりも、後で使用できるように指定する方が適切です。

于 2012-06-17T12:44:54.763 に答える
1

インスタンスを適切に破棄し、SqlCommandインスタンスへの参照がいくつあるかは問題ではありません。とにかく、それらはすべて同じインスタンスを指しています。

ただし、CommandTimeout破棄されたオブジェクトでも例外は発生しません。

于 2012-06-17T09:41:55.357 に答える