11using System ;
2- using System . Collections . Generic ;
2+ using System . Collections . Concurrent ;
33using System . IO ;
44using System . Linq ;
55using System . Threading ;
@@ -9,7 +9,7 @@ namespace Files.Backend.Services.SizeProvider
99{
1010 public class DrivesSizeProvider : ISizeProvider
1111 {
12- private readonly IDictionary < string , ISizeProvider > providers = new Dictionary < string , ISizeProvider > ( ) ;
12+ private readonly ConcurrentDictionary < string , ISizeProvider > providers = new ( ) ;
1313
1414 public event EventHandler < SizeChangedEventArgs > ? SizeChanged ;
1515
@@ -19,35 +19,31 @@ public async Task CleanAsync()
1919 var oldDriveNames = providers . Keys . Except ( currentDrives ) . ToArray ( ) ;
2020
2121 foreach ( var oldDriveName in oldDriveNames )
22- {
23- if ( providers . ContainsKey ( oldDriveName ) )
24- {
25- providers . Remove ( oldDriveName ) ;
26- }
27- }
22+ providers . TryRemove ( oldDriveName , out _ ) ;
23+
2824 foreach ( var provider in providers . Values )
29- {
3025 await provider . CleanAsync ( ) ;
31- }
3226 }
3327
3428 public async Task ClearAsync ( )
3529 {
36- foreach ( var provider in providers )
37- {
38- await provider . Value . ClearAsync ( ) ;
39- }
30+ foreach ( var provider in providers . Values )
31+ await provider . ClearAsync ( ) ;
32+
4033 providers . Clear ( ) ;
4134 }
4235
36+ /// <summary>
37+ /// Delegate the update to an instance of CachedSizeProvider.
38+ /// This method is reentrant (thread safe) to avoid having to await each result.
39+ /// </summary>
4340 public Task UpdateAsync ( string path , CancellationToken cancellationToken )
4441 {
4542 string driveName = GetDriveName ( path ) ;
46- if ( ! providers . ContainsKey ( driveName ) )
43+ var provider = providers . GetOrAdd ( driveName , ( key ) =>
4744 {
48- CreateProvider ( driveName ) ;
49- }
50- var provider = providers [ driveName ] ;
45+ return CreateProvider ( ) ;
46+ } ) ;
5147 return provider . UpdateAsync ( path , cancellationToken ) ;
5248 }
5349
@@ -65,11 +61,11 @@ public bool TryGetSize(string path, out ulong size)
6561
6662 private static string GetDriveName ( string path ) => Directory . GetDirectoryRoot ( path ) ;
6763
68- private void CreateProvider ( string driveName )
64+ private ISizeProvider CreateProvider ( )
6965 {
7066 var provider = new CachedSizeProvider ( ) ;
7167 provider . SizeChanged += Provider_SizeChanged ;
72- providers . Add ( driveName , provider ) ;
68+ return provider ;
7369 }
7470
7571 private void Provider_SizeChanged ( object ? sender , SizeChangedEventArgs e )
0 commit comments