Why isn't there an asynchronous file delete in .net?

.NetFile IoAsynchronous

.Net Problem Overview


You have the asynchronous versions of read and write (begin/end functions), but not of delete (that I can tell). Is there any reason for this? Isn't there as much reason to do delete asynchronously as read/write?

Using threading to simulate asynchronous behavior is not the same as asynchronous functions. Big difference, sure you get the perceived parallel processing, but it's not really preventing blocking, that other thread is still blocked waiting for the file i/o to complete. The real asynchronous functions (begin/end functions) operate at a system level, they queue up file i/o, let the application proceed, and let the application know when it is ready to proceed with the file i/o (allowing you to do other things while you wait for the file i/o to come available).

.Net Solutions


Solution 1 - .Net

This would be useful. DeleteFile could take up to 30s if deleting on a disconnected network share.

The reason is likely to be that there is no native function to delete a file asynchronously. The managed APIs generally are wrappers around the unmanaged ones.


Now why is there no native asynchronous file delete API? Native async deletion is hard to implement on Windows as it is. DeleteFile does in pseudocode CreateFile plus NtSetInformationFile(Disposition, Delete) plus CloseHandle. There is no async CreateFile (in my opinion a design bug in Windows). NtSetInformationFile just sets a flag on the file data structure in the kernel. It can't be asynchronous. The actual deletion happens when the last handle is closed. I think this might make CloseHandle blocking which is another design issue in Windows. There is no async CloseHandle.

Solution 2 - .Net

How about this:

public static class FileExtensions {
   public static Task DeleteAsync(this FileInfo fi) {
      return Task.Factory.StartNew(() => fi.Delete() );
   }
}

Then you can just do:

FileInfo fi = new FileInfo(fileName);
await fi.DeleteAsync(); // C# 5
fi.DeleteAsync().Wait(); // C# 4

Solution 3 - .Net

The File class doesn't expose an asynchronous file deletion method; however, through the use of the FileStream class, an asynchronous file deletion can still be performed by taking advantage of a specific one of the 13 constructor overloads provided. The following code will delete a file asynchronously:

using (new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.None, 1, FileOptions.DeleteOnClose | FileOptions.Asynchronous)) ;

I haven't tested it very much, so you may have to modify the usage slightly. (You may want to change FileShare.None to something else if file access by other threads should not be blocked during deletion.) Also, since this code doesn't return any derivation of Task, it would probably be valid to run it with the Task.Run method. Basically, it performs a file deletion which is actually asynchronous on the I/O level, so offloading it onto a thread pool should be okay in this case.

Solution 4 - .Net

If nothing else has the file open, opening a FileStream with FileOptions.DeleteOnClose will cause Windows delete the file when the stream is closed. This may help you if you're already opening a FileStream to do async reading/writing, though if you need to wait for the deletion to finish it doesn't help you (although according to @JoelFan waiting for File.Delete to finish doesn't guarantee the file is actually deleted anyway).

Interestingly enough, in testing against a network share, it seems that opening the stream as such and doing nothing with it is significantly faster (~40%) than File.Delete:

using (new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose)) { }

Solution 5 - .Net

I may be wrong, but in the case someone tries to access the same file on a cross thread operation, it would be needed to block the file for access until the delete operation is completed.

Solution 6 - .Net

Perhaps because you can just as easily do it yourself?

var t = Task.Factory.StartNew(() => File.Delete("file.txt"));
// ...
t.Wait();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaepheusView Question on Stackoverflow
Solution 1 - .NetusrView Answer on Stackoverflow
Solution 2 - .NetMichael KennedyView Answer on Stackoverflow
Solution 3 - .NetAlex FanatView Answer on Stackoverflow
Solution 4 - .NetejohnsonView Answer on Stackoverflow
Solution 5 - .NetRodrigo VedovatoView Answer on Stackoverflow
Solution 6 - .NetBranko DimitrijevicView Answer on Stackoverflow