Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

c# - When using yield within a "using" statement, when does Dispose occur?

I have a question regarding deferred execution and the disposing of data.

Consider the following example:

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++;
        }
    }
}

Will the break statement immediately cause the reader in ParseFile to dispose or is it still considered in context and will lock the file open until the program itself is closed?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So we have several separate issues going on here.

First off, dealing with the using in the iterator block. IEnumerator extends IDisposable. The code that generates iterator blocks is actually robust enough that any try/finally blocks (a using results in a try/finally block being created) results in the contents of the finally block being called in the Dispose method of the enumerator, if it wasn't already called. So as long as the enumerator is disposed, it won't leak the StreamReader.

So now we ask ourselves if the enumerator is disposed. All foreach statements will call Dispose on the enumerator (should it implement IDisposable). They do so even if you exit using a break or return statement, as well as when it finishes normally.

So you can be sure that under all circumstances the resource won't be leaked, barring the cases where nothing can be prevented from leaking (i.e. someone unpugging the machine).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...