23

我希望有一个File.ExistsAsync()

我有:

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

为此使用线程感觉就像是一种反模式。有没有更清洁的方法?

4

3 回答 3

4

There is no cleaner way than your solution.

The problems of race conditions aside I believe your solution can be used in some situations. e.g.

I have static file content in many different folders. (in my case cshtml views,script files, css files, for mvc) These files (which do not change much, during application execution) are always checked for in every request to the webserver, due to my application architecture, there are alot more places that files are checked for than in the default mvc application. So much so that file.exists takes up quite a portion of time each request.

so race conditions will generally not happen. The only interesting question for me is performance

starting a task with Task.Factory.StartNew() takes 0.002 ms (source Why so much difference in performance between Thread and Task?)

calling file.exists takes "0.006255ms when the file exists and 0.010925ms when the file does not exist." [Richard Harrison]

so by simple math calling the async File.Exists takes 0.008 ms up to 0.012 ms

in the best case async File.Exists takes 1.2 times as long as File.Exists and in the worst case it takes 1.3 times as long. (in my case most paths that are searched do not exist) so most of the time a File.Exists is mostly close to 0.01 ms

so it is not that much overhead, and you can utilize multiple cores/ harddisk controllers etc. more efficiently. With these calculations you can see that asynchroniously checking for existence of 2 files you will already have a performance increase of 1.6 in the worst case (0.02/ 0.012 )

well i'm just asyning async File.Exists is worth it in specific situations.

caveats of my post: i might have not calculated everything correctly i rounded alot i did not measure performance on a single pc i took performance from other posts i just added the time of File.Exists and Task.Factory.StartNew() (this may be wrong) i disregard alot of sideffects of multithreading

于 2013-12-15T16:33:02.437 回答
2

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

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

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

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

于 2020-12-22T11:20:59.347 回答
-10

没有 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.5967 毫秒,而 File.OpenRead 需要 0.3927 毫秒)

也许如果你能详细说明你为什么这样做,我们就能更好地回答;在那之前我会说你不应该这样做

于 2013-09-29T10:51:56.473 回答