Narendra
Narendra

Reputation: 1412

Delete file using file watcher not allowing me to delete second time

My task is to delete file once the processing is completed . I am using FileWatcher to complete this task. It is watching specific folder . Suppose If i copy one file and put that in filewatcher folder it is deleting. Second time when i copy the same file and paste that in the same watching folder. This time it says that Another process is using that file . and exception is throwing . I think i am missing something. Here is my code

private static void Main(string[] args)
    {

       var fw = new FileSystemWatcher(EmailSetting.DataFolder)
        {
            IncludeSubdirectories = false
            ,
            EnableRaisingEvents = true

        };
        fw.Created += (sender, e) =>
        {
         File.Delete(e.FullPath);

        };
        Console.ReadLine();
    }

Upvotes: 0

Views: 864

Answers (1)

Oliver
Oliver

Reputation: 45071

You receive the Created event when the file was created (hence the name). But at this point in time the other process that is actually creating it, didn't finish writing content into that file. So the file might be already there, but the other is still working on it (imagine you would copy a 8 GB file).

It would be wiser to simply write the path of the file into a list within the event and let another thread regularly check this concurrent bag (e.g. once a second). First it checks if the file exists and if yes, try to delete it. If succeeded, remove it from the bag, otherwise try again next time.

Code example

private static readonly ConcurrentQueue<FileInfo> _FileCandidates = new ConcurrentQueue<FileInfo>();

private static void Main(string[] args)
{
    var watcher = new FileSystemWatcher
    {
        Path = @"R:\TestFolder",
        IncludeSubdirectories = false,
        Filter = "*.*",
    };

    Console.WriteLine("Start watching folder... " + watcher.Path);
    watcher.Created += OnFileCreated;
    watcher.EnableRaisingEvents = true;

    var timer = new Timer
    {
        AutoReset = true,
        Interval = 1000,
    };

    timer.Elapsed += OnTimerElapsed;
    timer.Enabled = true;

    Console.ReadKey();
}

static void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
    FileInfo file;
    var stillInUseFiles = new List<FileInfo>();

    Console.WriteLine("Check for file candidates...");
    while (_FileCandidates.TryDequeue(out file))
    {
        try
        {
            Console.WriteLine("Delete " + file.FullName);

            if (file.Exists)
                file.Delete();
        }
        catch (IOException)
        {
            Console.WriteLine("Could not delete file, try again next time.");
            stillInUseFiles.Add(file);
        }
    }

    foreach (var unhappyFile in stillInUseFiles)
    {
        _FileCandidates.Enqueue(unhappyFile);
    }
}

static void OnFileCreated(object sender, FileSystemEventArgs e)
{
    Console.WriteLine("Found new file candidate " + e.FullPath);
    _FileCandidates.Enqueue(new FileInfo(e.FullPath));
}

Upvotes: 1

Related Questions