33
44using System . Collections . Concurrent ;
55using System . IO ;
6+ using System . Runtime . InteropServices ;
67using Windows . Win32 ;
78using Windows . Win32 . Storage . FileSystem ;
89
@@ -29,9 +30,9 @@ await Parallel.ForEachAsync(
2930 _paths ,
3031 cancellationToken ,
3132 async ( path , token ) => await Task . Factory . StartNew ( ( ) =>
32- {
33- ComputeSizeRecursively ( path , token ) ;
34- } ,
33+ {
34+ ComputeSizeRecursively ( path , token ) ;
35+ } ,
3536 token ,
3637 TaskCreationOptions . LongRunning ,
3738 TaskScheduler . Default ) ) ;
@@ -63,34 +64,48 @@ unsafe void ComputeSizeRecursively(string path, CancellationToken token)
6364
6465 if ( ! hFile . IsNull )
6566 {
66- do
67+ try
6768 {
68- FILE_FLAGS_AND_ATTRIBUTES attributes = ( FILE_FLAGS_AND_ATTRIBUTES ) findData . dwFileAttributes ;
69-
70- if ( attributes . HasFlag ( FILE_FLAGS_AND_ATTRIBUTES . FILE_ATTRIBUTE_REPARSE_POINT ) )
71- // Skip symbolic links and junctions
72- continue ;
73-
74- var itemPath = Path . Combine ( directory , findData . cFileName . ToString ( ) ) ;
75-
76- if ( attributes . HasFlag ( FILE_FLAGS_AND_ATTRIBUTES . FILE_ATTRIBUTE_DIRECTORY ) )
69+ do
7770 {
78- ComputeFileSize ( itemPath ) ;
71+ FILE_FLAGS_AND_ATTRIBUTES attributes = ( FILE_FLAGS_AND_ATTRIBUTES ) findData . dwFileAttributes ;
72+
73+ if ( attributes . HasFlag ( FILE_FLAGS_AND_ATTRIBUTES . FILE_ATTRIBUTE_REPARSE_POINT ) )
74+ // Skip symbolic links and junctions
75+ continue ;
76+
77+ var itemPath = Path . Combine ( directory , findData . cFileName . ToString ( ) ) ;
78+
79+ // Skip current and parent directory entries
80+ var fileName = findData . cFileName . ToString ( ) ;
81+ if ( fileName . Equals ( "." , StringComparison . OrdinalIgnoreCase ) ||
82+ fileName . Equals ( ".." , StringComparison . OrdinalIgnoreCase ) )
83+ {
84+ continue ;
85+ }
86+
87+ if ( attributes . HasFlag ( FILE_FLAGS_AND_ATTRIBUTES . FILE_ATTRIBUTE_DIRECTORY ) )
88+ {
89+ queue . Enqueue ( itemPath ) ;
90+ }
91+ else
92+ {
93+ ComputeFileSize ( itemPath ) ;
94+ }
95+
96+ if ( token . IsCancellationRequested )
97+ break ;
7998 }
80- else if ( findData . cFileName . ToString ( ) is string fileName &&
81- fileName . Equals ( "." , StringComparison . OrdinalIgnoreCase ) &&
82- fileName . Equals ( ".." , StringComparison . OrdinalIgnoreCase ) )
99+ while ( PInvoke . FindNextFile ( hFile , & findData ) ) ;
100+ }
101+ finally
102+ {
103+ if ( ! PInvoke . FindClose ( hFile ) )
83104 {
84- queue . Enqueue ( itemPath ) ;
105+ var error = Marshal . GetLastWin32Error ( ) ;
85106 }
86-
87- if ( token . IsCancellationRequested )
88- break ;
89107 }
90- while ( PInvoke . FindNextFile ( hFile , & findData ) ) ;
91108 }
92-
93- PInvoke . CloseHandle ( hFile ) ;
94109 }
95110 }
96111 }
0 commit comments