Async wait for file to be created

后端 未结 4 1009
别那么骄傲
别那么骄傲 2020-12-10 04:05

What would be the cleanest way to await for a file to be created by an external application?

    async Task doSomethingWithFile(string filepath)         


        
4条回答
  •  长情又很酷
    2020-12-10 04:26

    So the first key point is that you can use a FileSystemWatcher to be notified when a file system event changes at a particular path. If you, for example, want to be notified when a file is created at a particular location you can find out.

    Next, we can create a method that uses a TaskCompletionSource to trigger the completion of a task when the file system watcher triggers the relevant event.

    public static Task WhenFileCreated(string path)
    {
        if (File.Exists(path))
            return Task.FromResult(true);
    
        var tcs = new TaskCompletionSource();
        FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path));
    
        FileSystemEventHandler createdHandler = null;
        RenamedEventHandler renamedHandler = null;
        createdHandler = (s, e) =>
        {
            if (e.Name == Path.GetFileName(path))
            {
                tcs.TrySetResult(true);
                watcher.Created -= createdHandler;
                watcher.Dispose();
            }
        };
    
        renamedHandler = (s, e) =>
        {
            if (e.Name == Path.GetFileName(path))
            {
                tcs.TrySetResult(true);
                watcher.Renamed -= renamedHandler;
                watcher.Dispose();
            }
        };
    
        watcher.Created += createdHandler;
        watcher.Renamed += renamedHandler;
    
        watcher.EnableRaisingEvents = true;
    
        return tcs.Task;
    }
    

    Note that this first checks if the file exists, to allow it to exit right away if applicable. It also uses both the created and renamed handlers as either option could allow the file to exist at some point in the future. The FileSystemWatcher also only watches directories, so it's important to get the directory of the specified path and then check the filename of each affected file in the event handler.

    Also note that the code removes the event handlers when it's done.

    This allows us to write:

    public static async Task Foo()
    {
        await WhenFileCreated(@"C:\Temp\test.txt");
        Console.WriteLine("It's aliiiiiive!!!");
    }
    

提交回复
热议问题