22

実行の延期とデータの破棄について質問があります。

次の例を考えてみましょう。

private IEnumerable<string> ParseFile(string fileName)
{
    using(StreamReader sr = new StreamReader(fileName))
    {
        string line;
        while((line = sr.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

private void LineReader(string fileName)
{
    int counter = 0;

    foreach(string line in ParseFile(fileName))
    {
        if(counter == 2)
        {
            break; // will this cause a dispose on the StreamReader?
        } else
        {
            Console.WriteLine(line);
            counter++;
        }
    }
}

breakステートメントはすぐにリーダーを破棄させますParseFileか、それともコンテキストで考慮され、プログラム自体が閉じられるまでファイルを開いたままロックしますか?

4

1 に答える 1

18

したがって、ここではいくつかの個別の問題が発生しています。

まずusing、イテレータブロックでを処理します。 IEnumerator拡張しIDisposableます。イテレータブロックを生成するコードは実際には十分に堅牢であるため、try / finalブロック(using結果としてブロックが作成されます)では、ブロックtry/finallyのコンテンツがまだ呼び出されていない場合は、列挙子のメソッドで呼び出されます。列挙子が破棄されている限り、それはリークしません。finallyDisposeStreamReader

そこで、列挙子が破棄されているかどうかを自問します。すべてのforeachステートメントはDispose列挙子を呼び出します(実装する必要がありますIDisposable)。breakまたはreturnステートメントを使用して終了した場合でも、正常に終了した場合でもそうします。

したがって、すべての状況でリソースがリークされないことを確認できます。ただし、リークを防ぐことができない場合(つまり、誰かがマシンのプラグを抜く場合)は除きます。

于 2013-01-07T21:07:10.233 に答える