检查文件是否存在异步?

时间:2013-09-29 09:55:08

标签: c# async-await file-exists

我希望有File.ExistsAsync()

我有:

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

使用线程感觉就像反模式一样。 有更清洁的方式吗?

4 个答案:

答案 0 :(得分:3)

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

除了种族条件的问题外,我相信您的解决方案可以在某些情况下使用。 e.g。

我在许多不同的文件夹中都有静态文件内容。 (在我的例子中,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 :(得分: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)

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

答案 2 :(得分:2)

这个帖子很久了,但我今天找到了......

ExistsAsync 绝对应该是一回事。实际上,在 UWP 中,您必须使用 Async 方法来确定文件是否存在,因为它可能需要超过 50 毫秒的时间(任何“可能”需要超过 50 毫秒的时间在 UWP 语言中都应该是异步的)。

然而,这不是 UWP。我需要它的原因是检查 folder.exists 是否在网络共享、远程磁盘或空闲磁盘上会阻塞 UI。所以我可以把所有的消息,比如“检查...”,但如果没有 aysnc(或 ViewModel,或 timers 等),UI 不会更新

bool exists = await Task.Run(() => File.Exists(fileName)); 完美运行。在我的代码中,我同时拥有 (ExistsExistsAsync),因此我可以在非 UI 线程上运行时运行 Exists(),而不必担心开销。

答案 3 :(得分:-1)

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