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).