c# file-io using deferred-execution

c# - Cuando se usa el rendimiento dentro de una declaración de "uso", ¿cuándo ocurre Dispose?



file-io using (1)

Tengo una pregunta sobre la ejecución diferida y la disposición de datos.

Considere el siguiente ejemplo:

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

¿La declaración de break hará que el lector en ParseFile deshaga de inmediato o aún se considera en contexto y bloqueará el archivo abierto hasta que el programa se cierre?


Así que tenemos varios problemas por separado aquí.

En primer lugar, tratar con el using en el bloque iterador. IEnumerator extiende IDisposable . El código que genera bloques de iteradores es en realidad lo suficientemente robusto como para que cualquier bloque try / finally (un using resultados en un bloque try/finally creado) resulte en el contenido del bloque finally que se llama en el método Dispose del enumerador, si es que ya no se llama Por lo tanto, mientras se elimine el enumerador, no se filtrará el StreamReader .

Así que ahora nos preguntamos si el enumerador está dispuesto. Todas las declaraciones de foreach llamarán a Dispose en el enumerador (si se implementa como IDisposable ). Lo hacen incluso si sale usando una instrucción break o return , así como cuando termina normalmente.

Por lo tanto, puede estar seguro de que, en todas las circunstancias, el recurso no se filtrará, salvo en los casos en que no se pueda evitar que se filtre nada (es decir, que alguien desenchufe la máquina).