Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a file Exists async?

I wish there was a File.ExistsAsync()

I have:

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

Using a thread for this feels like an antipattern. Is there a cleaner way?

like image 585
Johan Larsson Avatar asked Sep 29 '13 09:09

Johan Larsson


2 Answers

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

like image 62
toeb Avatar answered Nov 08 '22 22:11

toeb


Long time since this thread, but I found it today...

ExistsAsync should definitely be a thing. In fact, in UWP, you have to use Async methods to find out if a file exists, as it could take longer than 50ms (anything that 'could' take longer than 50ms should be async in UWP language).

However, this is not UWP. The reason I need it is to check for folder.exists which if on a network share, remote disk, or idle disk would block the UI. So I can put all the messages like "checking..." but the UI wouldn't update without aysnc (or ViewModel, or timers, etc.)

bool exists = await Task.Run(() => File.Exists(fileName)); works perfectly. In my code, I have both (Exists and ExistsAsync) so that I can run Exists() when running on a non UI thread and don't have to worry about the overhead.

like image 2
David Hitchen Avatar answered Nov 08 '22 22:11

David Hitchen