Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After Directory.Delete the Directory.Exists returning true sometimes?

Tags:

c#

.net

io

I have very weird behavior. I have,

Directory.Delete(tempFolder, true);
if (Directory.Exists(tempFolder))
{
}

Sometimes Directory.Exists return true. Why? May be the explorer is open?

like image 479
Imran Qadir Baksh - Baloch Avatar asked Jun 17 '14 13:06

Imran Qadir Baksh - Baloch


People also ask

Which method is used to delete folder?

The rm command removes complete directories, including subdirectories and files. The rmdir command removes empty directories.

How do you force delete a file in C#?

So, all you really have to do is call WipeFile and supply the full path of the file to be deleted, as well as the number of times you want to overwrite it.

Which choice will delete a directory and all subdirectories C#?

To delete the specified directory and all its subdirectories, use the Directory. Delete() method.

Why is the directory specified by path not empty?

The directory is the application's current working directory. The directory specified by path is not empty. The directory is read-only or contains a read-only file. The directory is being used by another process.

Is the directory specified by path read-only or recursive?

The directory specified by path is read-only, or recursive is false and path is not an empty directory. The directory is the application's current working directory. The directory contains a read-only file.

Why is the directory read-only?

The directory is the application's current working directory. The directory contains a read-only file. The directory is being used by another process. The caller does not have the required permission.

What is the difference between the DeleteFile and removedirectory functions?

The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED." The RemoveDirectory function marks a directory for deletion on close.


1 Answers

Directory.Delete calls the Windows API function RemoveDirectory. The observed behavior is documented:

The RemoveDirectory function marks a directory for deletion on close. Therefore, the directory is not removed until the last handle to the directory is closed.

The .NET documentation is unfortunately missing this information. Whether the static Directory.Delete method opens a handle to the directory is not documented. Likewise, if it does, it is not documented when the handle is closed.

Without any of this information, the best you can do is to poll for completion:

Directory.Delete(tempFolder, true);
while (Directory.Exists(tempFolder)) Thread.Sleep(0);
// At this point the directory has been removed from the filesystem

Even though polling should generally be avoided in preference of events, installing a filesystem watcher would be a bit over the top for this. Still, keep in mind, that this operation does not come for free, particularly when dealing with a network drive.


Update: With .NET's Reference Source available, the implementation of Directory.Delete can be inspected. The first action of this method is to iterate over all files and delete them. The iteration is implemented using FindFirstFile/FindNextFile. The returned handle is stored as a SafeFindHandle, a concrete subclass of SafeHandle. As the documentation points out, the native handle is freed through a concrete ReleaseHandle override. ReleaseHandle is called from a (postponed) critical finalizer. Since finalization is non-deterministic, this explains the open handle, responsible for the delayed directory delete.

This information, however, does not help in finding a better solution than the one described above (polling for completion).


Other answers to this question did not identify the core issue, and work by coincidence at best. BanksySan's answer adds unrelated code that introduces a delay to allow time for open handles to be closed. Byeni's answer is closer, yet still off: When he talks about the object referencing the directory he almost nails it. However, the object referencing the directory is called a handle, a native resource. Native resources are disposed of in finalizers, and GC.Collect() does not run finalizers. This, too, appears to work by buying extra time.
like image 80
IInspectable Avatar answered Oct 05 '22 00:10

IInspectable