简体   繁体   中英

Wait for all files to be deleted using FileSystemWatcher

I have a console app that need to monitor a specific directory and wait for all files to be deleted for a specific amount of time. If after that time has exceeded and all of the files has not been deleted yet, I need the program to throw an exception. How can I accomplish this?

    public static void FileWatcher(string fileName, int timeToWatch)
    {
        FileSystemWatcher watcher = new FileSystemWatcher();

        try
        {
            watcher.Path = myPath;
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = string.Format("*{0}*", fileName);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
        }
        catch
        {
            throw;
        }
    }

You can use Task.Delay to setup a timeout (I assume timeToWatch is in milliseconds, if not then change it accordingly). If the directory has no more files (not checking subfolders) then it sets the other task as completed. The method will block ( WaitAny ) until either the timeout occurs or the files are all deleted. This can easily be changed to be async if required.

public static void FileWatcher(string fileName, int timeToWatch)
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    var timeout = Task.Delay(timeToWatch);
    var completedTcs = new TaskCompletionSource<bool>();

    watcher.Path = myPath;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.Filter = string.Format("*{0}*", fileName);
    watcher.Deleted += (s, e) => OnChanged(myPath, timeout, completedTcs);
    watcher.EnableRaisingEvents = true;

    OnChanged(myPath, timeout, completedTcs);

    // Wait for either task to complete
    var completed = Task.WaitAny(completedTcs.Task, timeout);

    // Clean up
    watcher.Dispose();

    if (completed == 1)
    {
        // Timed out            
        throw new Exception("Files not deleted in time");
    }
}

public static void OnChanged(string path, Task timeout, TaskCompletionSource<bool> completedTcs)
{
    if (!Directory.GetFiles(path).Any())
    {
        // All files deleted (not recursive)
        completedTcs.TrySetResult(true);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM