异步等待创建文件

await外部应用程序创建文件的最简洁方法是什么?

  async Task doSomethingWithFile(string filepath) { // 1. await for path exists // 2. Do something with file } 

因此,第一个关键点是,当文件系统事件在特定路径发生更改时,您可以使用FileSystemWatcher进行通知。 例如,如果您希望在特定位置创建文件时收到通知,则可以找到。

接下来,我们可以创建一个方法,该方法使用TaskCompletionSource在文件系统观察程序触发相关事件时触发任务的完成。

 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; } 

请注意,这首先检查文件是否存在,以允许它立即退出(如果适用)。 它还使用创建和重命名的处理程序,因为任一选项都可以允许文件在将来的某个时刻存在。 FileSystemWatcher也只监视目录,因此获取指定路径的目录然后检查事件处理程序中每个受影响文件的文件名很重要。

另请注意,代码在完成后会删除事件处理程序。

这允许我们写:

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

我就是这样做的:

 await Task.Run(() => {while(!File.Exists(@"yourpath.extension")){} return;}); //do all the processing 

您也可以将其打包成一个方法:

 public static Task WaitForFileAsync(string path) { if (File.Exists(path)) return Task.FromResult(null); var tcs = new TaskCompletionSource(); FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path)); watcher.Created += (s, e) => { if (e.FullPath.Equals(path)) { tcs.TrySetResult(null); if (watcher != null) { watcher.EnableRaisingEvents = false; watcher.Dispose(); } } }; watcher.Renamed += (s, e) => { if (e.FullPath.Equals(path)) { tcs.TrySetResult(null); if (watcher != null) { watcher.EnableRaisingEvents = false; watcher.Dispose(); } } }; watcher.EnableRaisingEvents = true; return tcs.Task; } 

然后只需使用它:

 await WaitForFileAsync("yourpath.extension"); //do all the processing