22 hours ago, Bas wrote
Does it block the calling thread: yes. Does it only return when all iterations are complete: no. After all, somebody may have called Stop or break during some iteration. Parrallel.ForEach returns a ParallelLoopResult structure which you can check to see if all iterations have run to completion.
Not sure what's going on in your code though.
But if I'm not calling Stop or Break anywhere, and there were no exceptions, I would expect that when Parrallel.ForEach returns then all iterations should have completed, correct?
22 hours ago, MasterPi wrote
In terms of your code, do you know if File.Delete always succeeeds? Like, you're not swallowing up the exception there, right?
I set VS to break when exceptions are thrown, and the very first exception that is thrown is at the last line (line 25 in the sample code). This implies all previous operations succeeded with no exceptions. Which implies all files and folders were successfully deleted.
Another thing I'm wondering is if there is some sort of a race condition. Like, you obtain a lock on the directory the moment you manipulate its contents (like delete). Then after all the deletes occur, you try to delete the directory before the lock is returned. If this is the case, then maybe let the directory delete spin in a while condition to check whether it CanDelete().
Yea that is what I'm trying to figure out. One would think from user code that the FS would be thread safe. Or at least if one thread returns from performing a FS operation, that the operation would be completely done, no matter if another thread then accesses the FS.
@evildictaitor: Yes the AV angle is a possibility. Didn't think of that. But why would the non-parallel version of the code then not have this issue?
@ScanIAm: I can look into such an algorithm but it seems such a simple task should not require to go to such lengths?
@Bass: Makes sense. I don't know what Windows is doing but it is SLOW in many cases compared to Linux.
13 hours ago
this MIGHT be relevant ?
The file / folder is NOT guranteed to be deleted right after DeleteFile returns and succeeded.
I think maybe you can trace the exact problem with ProcessMonitor.
It could very well be related to AV software, but then how do you explain the async version failing but the sync version succeeding in an otherwise identical environment?
11 hours ago
Why not call System.IO.Delete(path,true)? I don't know how many concurrent deletes $bitmap can take anyways. I suppose the answer to any scientific question is "Let's do an experiment."
Are you talking about System.IO.Directory.Delete? If so, I did that originally but that is what was slow. When the async version of my delete function works without running into this issue, it is ~40% faster, in some cases I've measured > 50% faster. So there is a possibility to speed things up, just trying to get to the bottom of what is causing the failures.
@cbae: I can look into such a solution of first deleting all files then folders.
BTW, shouldn't the file filter be "*" as opposed to "*.*"? Will it pick up files with no extensions?
In the actual implementation, the way I currently deal with this issue is to have N retries, so when it fails, I do a Thread.Sleep(100) and retry the operation up to N times. But out of curiosity I'm trying to understand why this is happening.