Di recente ho dovuto utilizzare 
System.IO.FileSystemWatcher per osservare una cartella ed accorgermi della 
creazione di nuovi files al suo interno.
In quell'occasione ho fatto 
esperienza di comportamenti anomali legati agli eventi di notifica dei 
cambiamenti nei files o cartelle.
Il caso fastidioso si verifica quando un 
file di grosse dimensioni arriva nella cartella: l'evento Created viene sparato 
quando inizia la scrittura fisica su disco, e non alla fine. Se all'interno del 
metodo legato all'evento si cerca di aprire il file si ottiene una bella 
eccezione di tipo System.IOException.
using System;
using System.IO;
namespace FSWTest
{
    class Program
    {
        static void Main(string[] args)
        {
            FileSystemWatcher fsw =
                new FileSystemWatcher(@"C:\Temp\FSWTest");
            fsw.Created += new FileSystemEventHandler(fsw_Created);
            fsw.EnableRaisingEvents = true;
            Console.Read();
        }
        static void fsw_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("{0} {1}", e.ChangeType, e.Name);
        }
    }
}
I miei colleghi ed io ipotizzavamo che questo 
comportamento fosse dovuto ad un baco del FileSystemWatcher del Framework 1.1, 
ma nel 2.0 le cose non cambiano.
Durante la ricerca di informazioni all'interno di gruppi di discussione ho 
avuto l'impressione che il baco sia localizzato a livello delle API di 
Windows:
- le API FileSystemWatcher di Windows non sparano l'evento Created 
nel modo giusto
- il FileSystemWatcher palleggia semplicemente gli 
eventi
- l'applicativo .NET deve fare attenzione a non aprire subito i nuovi 
files notificati
Una possibilità, anche se poco elegante, di gestire il comportamento anomalo dell'evento Created di 
FileSystemWatcher è quella di provare ad aprire il file fino a quando non si 
ottengono più eccezioni.
    //Questa è la mia classe wrapper di System.IO.FileSystemWatcher
    internal class FileSystemWatcherWrapper
    {
        FileSystemWatcher fileSystemWatcher = null;
        public FileSystemWatcherWrapper()
        {
            this.fileSystemWatcher = new FileSystemWatcher();
            this.fileSystemWatcher.Created +=
                new FileSystemEventHandler(fileSystemWatcher_Created);
        }
        public string Path
        {
            get { return this.fileSystemWatcher.Path; }
            set { this.fileSystemWatcher.Path = value; }
        }
        public string Filter
        {
            get { return this.fileSystemWatcher.Filter; }
            set { this.fileSystemWatcher.Filter = value; }
        }
        public bool EnableRaisingEvents
        {
            get { return this.fileSystemWatcher.EnableRaisingEvents; }
            set { this.fileSystemWatcher.EnableRaisingEvents = value; }
        }
        //Mio evento Created
        public event FileSystemEventHandler Created;
        private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
        {
            //Se nessuno si è agganciato da fuori non faccio nulla.
            if (null == this.Created)
                return;
            
            if (TryOpenFile(e.FullPath))
                this.Created(sender, e);
        }
        private bool TryOpenFile(string fullPath)
        {
            bool opened = false;
            //Se con 10 tentativi non riesco ad aprire il file me ne vado a casa.
            int milliseconds = 0;
            for (byte attempt = 0; attempt < 10; attempt++)
            {
                try
                {
                    milliseconds += 1000;
                    System.Threading.Thread.Sleep(milliseconds);
                    //Provo ad aprire il file
                    StreamReader sr = new StreamReader(fullPath);
                    //Se sono qui significa che non sono nel catch e l'apertura
                    //è andata bene -> quindi rilascio il file
                    sr.Dispose();
                    opened = true;
                    break;
                }
                catch (Exception ex)
                {
                    //...
                }
            }
            return opened;
        }
    }
Mitch
powered by IMHO 1.3