されることがあります。"を"ブロックのクライアントまで、フルのC#?[重複]
質問
この質問に答えはこちら
ある特定のインスタンスであるとの判断はいけない?) を使用"を"ブロック
using(SomeType t = new SomeType()){
...
}
解決
SomeType
クラスが実装 IDisposable
するます。
他のヒント
一部のオブジェクトは、あなたも一緒に終了した時に取るべきいくつかのアクションを必要としています。オブジェクトが処分される必要があるリソースのいくつかの種類を使用しているため、通常、これはあります。あなたは、クラスファイルのファイルオブジェクトがあり、このオブジェクトは、ファイルシステムからファイルを開く場合、ファイルシステム内のファイルを再び閉鎖する必要があります。
あなただけのファイルオブジェクトを残し、そしてfile.Closeに電話をするのを忘れた場合は()それはガベージコレクタ(GC)までにクリーンアップされないが走り、何もまだファイルオブジェクトを使用していなかった働きました。ガベージコレクタの実行が決定する共通言語ランタイム(CLR)に委ねられるべきとき。 GCはかなりしばらくの間、実行されない場合は、ファイルを終了した後、ファイルが長い間潜在的に開いたままでした。多くのファイルオブジェクトがある場合、これは大きな問題を提起することができ、または何かがファイルを開くしようとする場合がありますが、左のファイルオブジェクトがまだうろついていることができないため。
この問題を解決するために、C#がIDisposableをインターフェイスを持っています。これは、廃棄と呼ばれる一つの方法を持っています。いくつかのクリーンアップを必要とするクラスは、このDisposeメソッドを実装します。これは、あなたのリソースを使用するすべてのオブジェクトをクリーンアップするための標準的な方法を提供します。廃棄が呼び出されている必要があり、クラスがたくさんあります。これに伴う問題は、そのコードを処分するの呼び出しで覆われ、そしてあなたがオブジェクトをnew'edし、それをクリーンアップするためにdisposeを呼び出す場所が異なっているので、彼らは従うことは難しいですますです。だから、あなたは、コードの周りに多くのことを見て、正しい場所に配置して呼び出しがあったチェックするのは非常に慎重でなければならなかった。
この問題のC#を解決するには「を使用して」キーワードを導入しました。あなたがオブジェクトを新しい場所を中心に「を使用して」キーワードを置くことができ、これは処分があなたのためにそれを呼び出すことが保証されます。これは、usingステートメントの本体内でスローされた例外があっても...廃棄が起こるものは何でも呼び出されることを保証します。
だから、あなたがリソースを割り当て、オブジェクトがクリーンアップされることを確認したいとき「を使用して」を使用する必要があります。
<時間>を使用してのみ機能スタック、すなわち上に宣言されたオブジェクトのために使用することができます。これは、クラスのメンバとして宣言されているオブジェクトには機能しません。彼らにとって、あなたは自分自身を配置呼び出す必要があります。あなたはでは、それはそれを必要とする持っているオブジェクトを任意のメンバーに廃棄を呼び出すことができるように、あなたのクラスでのDisposeを実装する必要があります。
<時間>その上で呼ばれる使用して必要な一般的なオブジェクトは、次のとおりです。ファイル、データベース接続、などペンやブラシなどのGraphicsオブジェクト
。 <時間>あなたは二つの操作が一緒に起こるしたいとき時にはそれも使用されています。たとえば、ログ文を書きたい場合は、コードのブロックが入力されたときに、それが終了したときに、あなたがこのように使用することができ、ログクラスを書くことができます:
using( Log log = new Log("Doing stuff") )
{
// Stuff
}
ログクラスのコンストラクタは、メッセージを書き出すために作ることができる、とDisposeメソッドも、それを書くことができます。ファイナライザを実装(〜ログ)Disposeメソッドは、「を使用しては」「新しいログ」の周りに覚えていることを確認するために呼び出されていない場合。
アサートします使用 using
いつのタイプを実装し IDisposable
, ませんが、今でとれた try
/catch
ブロックがとにかく、使ってみるべきではないだろうかように見えます。)を使用 finally
ブロックです。
私は
のusing
文を持っている必要があり示された他の回答の多くを参照してください。私は特に、のないのusing
文を持っている必要がある場合に対処したい。
あなたは現在の関数のスコープ外にオブジェクトを使用する必要がある場合は、、using
ブロックを持っていません。良い例では、データベース接続またはDataReaderを返す必要があるメソッドを返すファクトリメソッドです。どちらの場合にも、あなたがそのための方法の外使用できないメソッドが返される前に、それが配置されることになるusing
文を使用して、あなたのオブジェクトを作成し、場合ます。
さて、あなたはまだあなたはまだどこかusing
文をお勧めしますので、これらのオブジェクトが配置されているのことをのことを確認したいです。ただ、オブジェクトが実際に作成された方法でそれを含んでいません。代わりに、あなたはusing
文で関数コール自体をラップすることができます。
SomeTypeがIDisposableインターを実装しています。
それはあなたへの手がかりSomeTypeをクリーンアップする必要があるアンマネージリソースを使用する開発者です。
例:
using(SqlConnection MyConnection = new SqlConnection("Connection string"))
{
MyConnection.Open();
//...
// 1. SQLConnection is a type that implements IDisposable
// 2. So you can use MyConnection in a using statement
// 3. When using block finishes, it calls Dispose method of
// SqlConnection class
// 4. In this case, it will probably close the connection to
// the database and dispose MyConnection object
}
あなたは、IDisposableを実装する独自のオブジェクトを作成することができます
public class MyOwnObjectThatImplementsIDisposable : IDisposable
{
//... some code
public void Dispose()
{
// Put here the code you want to be executed when the
// using statement finish.
}
}
は、使用して文でMyOwnObjectThanImplementsIDisposableタイプのオブジェクトを使用することができるようにます:
using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
{
// When the statement finishes, it calls the
// code you´ve writed in Dispose method
// of MyOwnObjectThatImplementsIDisposable class
}
ホープ、このことができます。
この文脈ではusing
文はIDisposableインターを実装する型に便利です。コードブロックはusing
文の範囲を出ると、Dispose()
が暗黙的に呼び出されます。あなたは、使用後すぐに処分したいオブジェクトを操作するとき、それは良い習慣です。
あなたはusing
ブロックを使用して注意する必要がありますする1つの特定のインスタンスは、のWCFサービスクライアントとのです。
WCFクライアントをラップする、このMSDNの記事のに述べたようにクライアントもたらすエラー(タイムアウトまたは通信の問題のような)故障状態のままにされているマスクができIDisposable
ブロックに(どのusing
を実装しません)。 Dispose()
は、と呼ばれるクライアントのClose()
方法火災、それが障害状態にありますので、エラーがスローされる。かいつまんで、元の例外は、第2の例外によってマスクされます。良いわけではありません。
MSDNの記事自体をはじめ、そこに様々な回避策があります。その他は、 IServiceOriented と blog.davidbarret.net を。
私自身は、最後の方法を好むます。
あなたは要約ルールをしたい場合。あなたがキャッチを持っていないでしょうIDisposableインターを使用していつでもオブジェクト、使用して使用します。使用して、基本的に、このパターンがあります:
try
{
//instantiate and use object
}
finally
{
//dispose object
}
あなたは良いことである、あなたのタイピングを保存することができます使用して、キャッチを必要としない場合ます。
主なルールは次のとおりです。 *使用するオブジェクトは、IDisposableインターフェイスを実装するときのステートメントを使用しました。
このインタフェースは、オブジェクトのリソースを解放する必要がありDisposeメソッドを提供します。このメソッドが呼び出されていない場合、オブジェクトは、CLRは、ガベージコレクションを実行するために望んでいるとして、限りメモリに滞在します。プログラマが最後に使用した後、ステートメントを使用する場合は、オブジェクトが配置され、すべてのリソースが無料になります。
使用されなくなったすべてのリソースがすぐに可能な限り自由であることが非常に重要です。
:それについての詳細はちょうどこのリンクをご覧ください。マイクロソフト
の多分それはLO C#のlangugeは以下れる「使用」の追加のためにその根本的な理由を言及する価値があります。例えば、DB接続。あなたはのtry / catchを使用する場合は/最後に、あなたは宙ぶらりんのコネクションで終わることはありませんが、GCがでキックしないと(明示的に閉じない場合)、これはしばらく時間がかかることができるまでの接続がぶら下がっままになります。あなたが使用している場合は、それを閉じるのを忘れて、いくつかの例外を使用してブロック内で発生した場合でも場合でも、あなたはすぐに接続を解除します(しゃれを言い訳)「を使用して」。
前のポストは言及してもう一つの理由は、プログラマは常にクリーンアップするために最終的には使用しないことです。例外の場合には、最後に使用していない場合、あなたは...
一つの状況がある。
ビルド(および使用中に呼び出す)使い捨てクラスのctorのは、アクションを実行することになり、その後、Disposeメソッドは、そのアクションを元に戻します。これは私がそれを使用する方法が一般的である。
他の人々はすでに "IDisposableを" について言及しています。
しかし、注意点の1文があることを「使用」を使用して、 キャッチされない「使用」の中にスローされた例外 でも「SomeType」は関係なく、配置されることになると思っています。
だから、次のスニペットで、
using (SomeType t = new SomeType()){
throw new Exception("thrown within using");
}
throw new Exception("thrown within using");
は無視すべきではありません。
私はまた、あなたが処分したいという何かがデータベース接続やファイルハンドルなどの非管理リソースへの保持している場合、何かがまたusing()
を実装した場合にそれがIDispose
ステートメントを使用して追加します。
Tは、名前とアドレスを保持しているList<T>
オブジェクトのようであり、そして、あなたがする必要はありません、Customer
を言うと、それは、通常のオブジェクトの場合。ガベージコレクタは、あなたのためにこれを管理するのに十分なスマートです。しかし、ガベージコレクタは、接続プールまたは近いファイルハンドルへの接続を返しません。