La classe FileSystemWatcher può risultare molto utile quando si vogliono monitorare file e folder. Nell'usarla bisogna però stare attenti a non scontrarsi con le funzionalità del sistema operativo ed in particolare con l'accesso esclusivo ai file. Cosa che ho imparato a mie spese ricevendo l'errore The process cannot access the file .... .
Questo errore accade perchè il file a cui si tenta di accedere, dopo la segnalazione del FileSystemWatcher, è ancora bloccato da un'altro processo (per esempio il processo di scrittura nella cartella monitorata). Per ovviare a questo problema ho inserito nella mia implementazione una metodo che verifica se il file è apribile oppure no. Ecco come si presenta il metodo:
private bool IsFileOpen(string fileName)
{
try
{
if (File.Exists(fileName))
{
FileStream stream = File.Open(fileName, FileMode.Open);
stream.Dispose();
}
return false;
}
catch (IOException ex)
{
ex = null;
return true;
}
}
Quest'ultimo viene chiamato dai metodi delegati alla gestione degli eventi Changed, Created, Deleted e Renamed per porre un periodo di attesa qualora il file non risulti disponibile:
while (IsFileOpen(e.FullPath) == true)
{
System.Threading.Thread.Sleep(250);
}
Per evitare loop infiniti, il codice andrebbe arricchito con un counter che limiti in qualche modo i cicli all'interno del while; per esempio in questo modo:
int counter = 0;
while (IsFileOpen(e.FullPath) == true && counter < 10)
{
System.Threading.Thread.Sleep(250);
counter++;
}
Sicuramente si possono trovare delle soluzioni più eleganti ma, per il momento, questa mi ha permesso di rimettere in produzione il servizio basato sul FileSystemWatcher che funzionava a singhiozzo. Sperando in un pò di tempo libero magari riuscirò a realizzare qualcosa più utile per risolvere questo problema.