11

使い捨てのリソースを利用する適切な方法はありますか? 返されたオブジェクトは IDisposable ですが、反復処理中の要素は IDisposable です。

次に例を示します。

public static IEnumerable<T> Fetch(IEnumerable<Guid> ids)
{
    using (var client = new CouchbaseClient())
    {
        yield return ids.Select(s => s.ToString());
    }
}

現在、これを呼び出しても、using取得したリソースは破棄されません。ToList にアクセスして一度にすべて返すことができることはわかっていますが、これを「適切に」処理する方法はありますか、または IDisposable リソースのタブを保持し、完了したら手動で破棄する必要がありますか?

4

1 に答える 1

7

IEnumeratorつまり、メソッドの呼び出し元がオブジェクトを適切に処理する限り、心配する必要はありません。

IEnumeratorを実装IDisposableし、イテレータ ブロックの作成に使用されるロジックは実際には、破棄されたときに未実行のすべての finally ブロックを実行するのに十分スマートです。using呼び出しの結果として finally ブロックが作成され、そこでIDisposableリソースが破棄されます。

したがって、これからIEnumerator作成されたオブジェクトIEnumerableが完全に反復されるか (この場合、最後のMoveNext呼び出しがusingブロックの最後に到達してリソースを破棄します)、IDisposableクライアントが破棄される限り、クライアントは破棄されます。

コードのユーザーがオブジェクトを適切に処理しないことが懸念される場合はIEnumerator、遅延評価で反復子ブロックを使用しないことをお勧めします。呼び出し元が「いい感じ」でなくても確実にメソッドを評価したい場合は、積極的にメソッドを評価します (つまり、コードを取得し、結果をリストにダンプしてから、そのリストを返します)。リソースを破棄しないことの結果が主に、または完全にパフォーマンスに関連している場合 (しばらくメモリを解放しない、接続を開いたままにしておくなど)、問題にならないかもしれませんが、ロックを永久に保持することが問題である場合重大な問題 (つまり、ロックされたリソースが解放されないとデッドロックが発生する可能性がある) の場合、遅延評価の利点は価値がない可能性があります。

于 2012-11-22T01:46:25.107 に答える