2010-01-21 26 views
11

Abro una transmisión y luego deserializo los datos en la transmisión. Sin embargo, agregué un miembro al objeto SavedEventSet por lo que ahora cuando intento abrir un archivo antiguo, arroja la excepción en la línea de deserialización.Cerrar una secuencia después de una excepción

Esto está bien conmigo (por ahora) pero el problema es que manejo la excepción, pero nunca cierro la secuencia (porque la excepción ocurrió antes de cerrar la transmisión), así que cuando intento abrir el archivo nuevamente, no me deja porque está en uso.

¿Cómo cierro la transmisión después de esta excepción? Si pongo stream.Close() en el catch o en el finally, se queja de intentar acceder a una variable local no asignada. Parece una mala práctica simplemente abrir un archivo aleatorio que sé que está allí. ¿Hay alguna forma de abrir una secuencia de forma similar a un constructor vacío para que parezca que está asignada?

Gracias

SavedEventSet sES; 
OpenFileDialog oFD = new OpenFileDialog(); 
Stream stream; 
BinaryFormatter bF; 

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
     stream = File.Open(oFD.FileName, FileMode.Open); 
     bF = new BinaryFormatter(); 

     sES = (SavedEventSet)bF.Deserialize(stream); 
     stream.Close(); 

    } 
} 
catch (Exception ex) 
{ 
    stream.Close(); 
    /*handle Exception*/ 
} 

Respuesta

26

Se puede utilizar un bloque de using, que se cerrará automáticamente la corriente, incluso si hay una excepción:

using(Stream stream = File.Open(oFD.FileName, FileMode.Open)) 
{ 
    bF = new BinaryFormatter(); 

    sES = (SavedEventSet)bF.Deserialize(stream); 
} 
+0

+1 para 'using()'. Detrás de escena se compila en un bloque try/catch, y garantiza que se llame 'Dispose()' - se puede usar en todos los implementadores de 'IDisposable' – STW

+0

Estoy de acuerdo, esto es exactamente lo que el bloque 'using' es para . – auujay

+0

Gracias :) Ni siquiera sabía sobre el uso de bloques. – EatATaco

6

Conjunto corriente a cero antes de que el bloque try.

En su captura, compruebe si la transmisión no es nula, de lo contrario cierre la secuencia.

SavedEventSet sES; 
    OpenFileDialog oFD = new OpenFileDialog(); 
    Stream stream = null; 
    BinaryFormatter bF; 

    try 
    { 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if (oFD.FileName.Contains(".sav")) 
    { 
     stream = File.Open(oFD.FileName, FileMode.Open); 
     bF = new BinaryFormatter(); 

     sES = (SavedEventSet)bF.Deserialize(stream); 
     stream.Close(); 

    } 
    } 
    catch (Exception ex) 
    { 
    if (stream != null) 
     stream.Close(); 
    /*handle Exception*/ 
    } 
+0

no entiendo por qué no es simplemente nula, para empezar. Pero funcionó, gracias :) – EatATaco

+0

Creo que el valor predeterminado es nulo, es decir, puede asignar nulo explícitamente solo para evitar posibles advertencias del compilador. – i486

4

Use un bloque finally, este se ejecutará si se ha producido o no una excepción:

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
    stream = File.Open(oFD.FileName, FileMode.Open); 
    bF = new BinaryFormatter(); 

    sES = (SavedEventSet)bF.Deserialize(stream); 
    } 
} 
catch (Exception ex) 
{ 
    /*handle Exception*/ 
} 
finally 
{ 
    if (stream != null) 
    stream.Close(); 
} 
+0

Esto en realidad no funciona. Obtengo el mismo problema de "variable local no asignada". – EatATaco

+0

También preferiría esta opción, pero para que funcione, necesita que la transmisión sea almacenada fuera del bloque try/catch/finally. –

+0

@Wagner Silveira: la ha creado fuera del bloque. – Oded

0
SavedEventSet sES; 
OpenFileDialog oFD = new OpenFileDialog(); 
BinaryFormatter bF; 

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
     using(Stream stream = File.Open(oFD.FileName, FileMode.Open)) 
     { 
      bF = new BinaryFormatter(); 

      sES = (SavedEventSet)bF.Deserialize(stream); 
      stream.Close(); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    /*handle Exception*/ 
} 
Cuestiones relacionadas