FileSystemWatcher, file in uso

giovedì 17 gennaio 2013 - 10.54
Tag Elenco Tags  C#  |  .NET 3.5

volperubbia Profilo | Senior Member

Ciao a tutti,
avrei bisogno di un consiglio su come gestire in un FileSystemWatcher l'errore di file in uso. Ho un'applicazione web e un'applicazione win che lavorano in parallelo.

Applicazione web
L'utente chiede un report e l'applicazione in una determinata cartella MyFolder sul server:
1) crea un file xml (XmlWriter) con estensione ".xml.tmp" con la richiesta del report;
2) fa un System.IO.File.Copy(file + ".xml.tmp", file + ".xml", true).

Applicazione win
Sulla cartella MyFolder del server c'è un FileSystemWatcher:
m_fileSystemWatcher = new FileSystemWatcher(MyFolder);
m_fileSystemWatcher.Filter = "*.xml";
m_fileSystemWatcher.Created += new FileSystemEventHandler(...);
m_fileSystemWatcher.EnableRaisingEvents = true;

In pratica si accorge che l'xml è stato creato, lo legge (XmlReader) e genera un pdf (stessa cartella e stesso nome file).
L'applicazione web ogni tot secondi guarda se in MyFolder c'è il pdf, appena compare apre un popup.

Il giro regge, ma a volte:

a) l'applicazione win quando va a leggere l'xml lo trova in uso. Meglio usare System.IO.File.Copy o System.IO.File.Move? Meglio usare m_fileSystemWatcher.Created o m_fileSystemWatcher.Renamed?

b) il pdf c'è ma non è ancora completamente creato, quindi nel popup tocca fare F5.

Qualche idea su come migliorare il ciclo? Ho inserito alcuni System.Threading.Thread.Sleep(...), ma mi sono accorto che dipende dal file system del server dove installi il tutto, su alcuni basta e su altri no.

Grazie per l'attenzione,
Davide

nico839 Profilo | Senior Member

Ciao, una volta una cosa simile è capitata anche a me e avevo messo una pezza con un cliclo wile prima di lavorare il file dove provare ad aprire il file in lettura ( se non ricordo male), se andava a buon fine (file libero) uscivo dal ciclo e procedevo con le operazioni, altrimenti thread.sleep e riprovavo e così via finchè il file non era libero. Certo rischi che ti rimanga tutto inchiodato all'infinito dentro il ciclo quindi ci vuole un controllo per uscire dal ciclo in questo caso.
Per la parte asp.net purtroppo non ne ho idea....
Ciao.
Nicolas

volperubbia Profilo | Senior Member

Ciao Nicolas,
sì al momento si potrebbe fare una cosa del tipo:

public bool IsFileInUse(string strFilename, int iTestNumber) {
bool objReturn = true;
for (int i = 0; i < iTestNumber; i++) {
System.Threading.Thread.Sleep(1 * 1000);
try
{
using (var stream = System.IO.File.Open(strFilename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) {
if (stream != null) {
objReturn = false;
break;
};
};
}
catch {
};
};
return objReturn;
}

con il parametro iTestNumber magari messo nell'App.config, in modo da evitare cicli infiniti, anche perchè se dopo N secondi ancora risulta in uso, allora ci sono dei problemi.

Davide

nico839 Profilo | Senior Member

Si esatto, avevo fatto una cosa simile!
Ciao.
Nicolas
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5