检查文件是否存在异步?

问题描述 投票:9回答:3

我希望有一个File.ExistsAsync()

我有:

bool exists = await Task.Run(() => File.Exists(fileName));

使用线程就像反模式一样。有更干净的方式吗?

c# async-await file-exists
3个回答
2
投票

可能有充分的理由没有File.ExistsAsync;因为拥有一个绝对没有意义; File.Exists不会花很长时间;我在文件存在时将其测试为0.006255ms,在文件不存在时测试为0.010925ms。

有几次调用File.Exists是明智的;但通常我认为正确的解决方案是打开文件(从而防止删除),捕获任何异常 - 因为无法保证在调用File.Exists后文件将继续存在。

如果要创建新文件而不覆盖旧文件:

File.Open("fn", FileMode.CreateNew)

对于大多数用例,我可以想到File.Open()(无论是现有的还是创建新的)会更好,因为一旦调用成功,你将拥有该文件的句柄并能够对它做一些事情。即使使用文件存在作为标志我也认为我仍然打开并关闭它。我真正使用File.Exists的唯一一次是在调用浏览器之前检查是否存在本地HTML文件,这样我就可以显示一条很好的错误消息。

在File.Exists之后,无法保证其他内容不会删除该文件;因此,如果您在使用File.Exists检查后打开它,则打开的调用仍然可能失败。

在我的测试中,使用网络驱动器上的FileExists需要比File.Open更长的时间,File.Exists需要1.5967ms,而File.OpenRead需要0.3927ms)

也许如果你可以扩展为什么你这样做我们会更好地回答;在那之前,我会说你不应该这样做


3
投票

没有比解决方案更清洁的方法了。

除了竞争条件的问题,我相信你的解决方案可以在某些情况下使用。例如

我在许多不同的文件夹中有静态文件内容。 (在我的情况下,cshtml视图,脚本文件,css文件,用于mvc)这些文件(在应用程序执行期间变化不大)总是在每次请求到web服务器时检查,由于我的应用程序架构,还有更多检查文件的位置是否在默认的mvc应用程序中。因此file.exists占用了每个请求的相当一部分时间。

所以竞争条件通常不会发生。对我来说唯一有趣的问题是表现

使用Task.Factory.StartNew()启动任务需要0.002毫秒(源Why so much difference in performance between Thread and Task?

调用file.exists在文件存在时为“0.006255ms,在文件不存在时为0.010925ms”。 [理查德哈里森]

所以通过简单的数学调用异步File.Exists需要0.008毫秒到0.012毫秒

在最好的情况下,async File.Exists的使用时间是File.Exists的1.2倍,在最坏的情况下需要1.3倍的时间。 (在我的情况下,搜索的大多数路径都不存在)所以大多数时候File.Exists大多接近0.01毫秒

所以它不是那么多开销,你可以更有效地利用多个核心/硬盘控制器等。通过这些计算,您可以看到异步检查是否存在2个文件,在最坏的情况下,性能会增加1.6(0.02 / 0.012)

好吧,我只是asyning async File.Exists在特定情况下是值得的。

我的帖子的警告:我可能没有正确计算一切我很多我没有测量单个电脑上的性能我从其他帖子中获取性能我只是添加了File.Exists和Task.Factory.StartNew()的时间(这可能是错的)我忽视了多线程的很多副作用


-1
投票

如果您针对网络上的计算机或foreach循环中的多台计算机执行File.Exists可能需要很长时间。至于被删除,这可能在任何时候发生。您能否提供有关特定任务的更多信息?例如,您只是检查它是否存在,您是否检查它是否存在,因为您要执行File.ReadLines等。

© www.soinside.com 2019 - 2024. All rights reserved.