ASP.NET C# – System.IO.IOException: Il processo non può accedere al file perché è in uso da un altro processo Come risolvere un classico errore di runtime durante l'esecuzione del metodo File.ReadAllBytes e/o di altri metodi similari che effettuano operazioni IO sul FileSystem

ASP.NET C# - System.IO.IOException: process can't access the file because it is being used by another process in File.ReadAllBytes - How to fix it

Qualsiasi sviluppatore C# che non sia alle prime armi ha utilizzato almeno una volta il metodo File.ReadAllBytes per leggere il contenuto di un file presente sul FileSystem in locale e acquisirne il contenuto in memoria. Il metodo è fondamentalmente un wrapper che apre un’istanza FileStream per leggere il contenuto del file, quindi legge il contenuto dello stream e restituisce il suo array di byte per utilizzi di vario tipo.

Come ben spiegato nella documentazione ufficiale, il FileStream sottostante viene aperto utilizzando il flag FileShare.Read in combinazione con FileAccess.Read, il che significa che le chiamate simultanee al metodo File.ReadAllBytes sullo stesso file sono consentite: in altre parole, non vedremo mai una eccezione di tipo System.IO. IOException a causa del fatto che il file è utilizzato da un altro processo… a meno che il processo in questione non lo abbia già aperto in scrittura! Qualora questo dovesse verificarsi, la presenza del flag FileShare.Read determinerà il fallimento dell’operazione con il seguente messaggio di errore:

 

System.IO.IOException: the process can’t access the file because it is being used by another process

System.IO.IOException: Il processo non può accedere al file perché è in uso da un altro processo.

Quando l’eccezione di cui sopra si verifica, abbiamo essenzialmente due strade da percorrere:

  • Attendere e riprovare fino al termine del writing lock, ovvero fino a quando il processo che sta scrivendo non ha terminato. Questo tipo di approccio è spiegato molto bene in questo thread su StackOverflow.
  • Rinunciare al metodo File.ReadAllBytes (e metodi similari) e aprire manualmente un FileStream utilizzando il flag FileShare.ReadWrite al posto del flagFileShare.Read, il quale è utilizzato internamente dai metodi File.ReadAllBytes e similari (come spiegato in questo altro thread sempre su StackOverflow).

Il primo workaroud è certamente percorribile, ma rischia di creare problematiche di thread-locking nel malaugurato caso in cui l’attività di scrittura del processo che si attende dovesse prolungarsi: per questo motivo è quasi sempre preferibile utilizzare il secondo metodo, a patto ovviamente di non avere esigenze particolari.

Ecco un rapido esempio di implementazione che mostra un metodo molto simile al classico File.ReadAllBytes ma con la possibilità aggiuntiva di specificare uno o più flag FileShare a piacere:

Per il momento è tutto: spero che questa breve analisi potrà rivelarsi d’aiuto a quanti si imbatteranno in questa problematica!

 

RELATED POSTS

About Ryan

IT Project Manager, Web Interface Architect e Lead Developer di numerosi siti e servizi web ad alto traffico in Italia e in Europa. Dal 2010 si occupa anche della progettazione di App e giochi per dispositivi Android, iOS e Mobile Phone per conto di numerose società italiane.

View all posts by Ryan