Domanda

Ho questo codice che salva un file pdf.

FileStream fs = new FileStream(SaveLocation, FileMode.Create);
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fs.Flush();
fs.Close();

Funziona bene. Tuttavia a volte non rilascia il blocco subito e quel file cause eccezioni con funzioni di blocco eseguito dopo questo periodo.

C'è un modo ideale per rilasciare il blocco file dopo fs.Close ()

È stato utile?

Soluzione

Ecco l'ideale:

using (var fs = new FileStream(SaveLocation, FileMode.Create))
{
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}

, che è più o meno equivalente a:

FileStream fs =  null;
try
{
    fs = new FileStream(SaveLocation, FileMode.Create);
    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
finally
{
    if (fs != null)
    {
        ((IDisposable)fs).Dispose();
    }
}

utilizzando essere più leggibile.


UPDATE:

@aron, ora che sto pensando

File.WriteAllBytes(SaveLocation, result.DocumentBytes);

aspetto ancora più bella per gli occhi che l'ideale: -)

Altri suggerimenti

Abbiamo visto questo stesso problema in produzione con un utilizzo () Dichiarazione avvolgendolo.

Una delle principali colpevoli qui è un software anti-virus che può entrare di nascosto dopo che il file è chiuso, afferrarlo per verificare che non contenga un virus prima di rilasciarlo.

Ma anche con tutti i software anti-virus fuori dal mix, nei sistemi di carico molto elevati con i file memorizzati su condivisioni di rete abbiamo ancora visto il problema di tanto in tanto. A, tosse, breve Thread.Sleep (), tosse, dopo la chiusura sembrava per curarla. Se qualcuno ha una soluzione migliore mi piacerebbe sentirla!

Non riesco a immaginare il motivo per cui il blocco sarebbe stato mantenuto dopo che il file viene chiuso. Ma si dovrebbe considerare avvolgere questo in un utilizzando statment per garantire che il file è chiuso, anche se viene sollevata un'eccezione

using (FileStream fs = new FileStream(SaveLocation, FileMode.Create))
{
  fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);  
}

Se le funzioni di esecuzione dopo questo fanno parte della stessa applicazione, quindi un approccio migliore potrebbe essere quella di aprire il file in lettura / scrittura all'inizio dell'intero processo, e quindi passare il file di ciascuna funzione senza chiudere fino alla fine del processo. Allora sarà inutile per l'applicazione per bloccare in attesa per l'operazione IO completa.

Questo ha funzionato per me quando si utilizza .Flush () ho dovuto aggiungere una stretta dentro l'istruzione using.

 using (var imageFile = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))
 {
     imageFile.Write(bytes, 0, bytes.Length);
     imageFile.Flush();
     imageFile.Close();
  }

Appena avuto lo stesso problema quando ho chiuso un FileStream e aprii immediatamente il file in un'altra classe. L'istruzione using non era una soluzione in quanto la FileStream era stato creato in un altro posto e conservati in un elenco. Cancellare l'elenco non è stato sufficiente.

Sembra che il torrente ha bisogno di essere liberato dal garbage collector prima che il file può essere riutilizzato. Se il tempo tra la chiusura e l'apertura è troppo breve, è possibile utilizzare

GC.Collect();

subito dopo aver chiuso il flusso. Questo ha funzionato per me.

Credo che le soluzioni di Ian Mercer per mettere il filo a dormire potrebbe avere lo stesso effetto, dando il tempo di GC per liberare le risorse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top