Why isn't there an asynchronous file delete in .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
.
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
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.