While working on the dotNetTips Dev Cleaner utility, I wanted to make the deletion of files even faster. While writing this utility I found and worked on speed issues, almost all relating to updating the user interface. So to decouple the deleting from the UI, I decided to add a new feature to the dotNetTips.Utility open source project.
Processor Class
I added a new class in the dotNetTips.Utility.IO namespace called Processor. The purpose of this class is to copy, move and delete files while firing events that can be used to update the UI. Unlike other methods I have used in other frameworks if an exception occurs, it fires an event and keeps processing.
First I created the event,
- public event EventHandler<ProgressEventArgs> Processed;
-
- protected virtual void OnProcessed(ProgressEventArgs e)
- {
- EventHandler<ProgressEventArgs> processedEvent = this.ProcessedEvent;
- if (processedEvent != null)
- {
- processedEvent(this, e);
- }
- }
- //The event above is called by the code below:
-
- public int DeleteFiles(IEnumerable<FileInfo> files)
- {
- Encapsulation.TryValidateParam(files, "files", "");
- int result = 0;
- IEnumerator<FileInfo> enumerator;
- try
- {
- enumerator = files.AsParallel<FileInfo>().GetEnumerator();
- while (enumerator.MoveNext())
- {
- FileInfo current = enumerator.Current;
- if (current.Exists)
- {
- try
- {
- current.Delete();
- result++;
- ProgressEventArgs e = new ProgressEventArgs();
- e.Name = current.FullName;
- e.ProgressState = ProgressState.Deleted;
- e.Size = current.Length;
- this.OnProcessed(e);
- continue;
- }
- catch (Exception ex)
- {
- ProjectData.SetProjectError(ex);
- ProgressEventArgs e1 = new ProgressEventArgs();
- e1.Name = current.FullName;
- e1.ProgressState = ProgressState.Error;
- e1.Size = current.Length;
- e1.Message = ex.Message;
- this.OnProcessed(e1);
- ProjectData.ClearProjectError();
- continue;
- }
- }
-
- ProgressEventArgs e2 = new ProgressEventArgs();
- e2.Name = current.FullName;
- e2.ProgressState = ProgressState.Error;
- e2.Size = current.Length;
- e2.Message = Resources.FileNotFound;
- this.OnProcessed(e2);
- }
- }
- finally
- {
- if (enumerator != null)
- {
- enumerator.Dispose();
- }
- }
-
- return result;
- }
This new class helped my utility go from deleting 1K files per second to up to around 2K per second!