1
1
using System ;
2
- using System . Collections . Generic ;
2
+ using System . Collections . Concurrent ;
3
3
using System . IO ;
4
4
using System . Linq ;
5
5
using System . Threading ;
@@ -9,7 +9,7 @@ namespace Files.Backend.Services.SizeProvider
9
9
{
10
10
public class DrivesSizeProvider : ISizeProvider
11
11
{
12
- private readonly IDictionary < string , ISizeProvider > providers = new Dictionary < string , ISizeProvider > ( ) ;
12
+ private readonly ConcurrentDictionary < string , ISizeProvider > providers = new ( ) ;
13
13
14
14
public event EventHandler < SizeChangedEventArgs > ? SizeChanged ;
15
15
@@ -19,35 +19,31 @@ public async Task CleanAsync()
19
19
var oldDriveNames = providers . Keys . Except ( currentDrives ) . ToArray ( ) ;
20
20
21
21
foreach ( var oldDriveName in oldDriveNames )
22
- {
23
- if ( providers . ContainsKey ( oldDriveName ) )
24
- {
25
- providers . Remove ( oldDriveName ) ;
26
- }
27
- }
22
+ providers . TryRemove ( oldDriveName , out _ ) ;
23
+
28
24
foreach ( var provider in providers . Values )
29
- {
30
25
await provider . CleanAsync ( ) ;
31
- }
32
26
}
33
27
34
28
public async Task ClearAsync ( )
35
29
{
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
+
40
33
providers . Clear ( ) ;
41
34
}
42
35
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>
43
40
public Task UpdateAsync ( string path , CancellationToken cancellationToken )
44
41
{
45
42
string driveName = GetDriveName ( path ) ;
46
- if ( ! providers . ContainsKey ( driveName ) )
43
+ var provider = providers . GetOrAdd ( driveName , ( key ) =>
47
44
{
48
- CreateProvider ( driveName ) ;
49
- }
50
- var provider = providers [ driveName ] ;
45
+ return CreateProvider ( ) ;
46
+ } ) ;
51
47
return provider . UpdateAsync ( path , cancellationToken ) ;
52
48
}
53
49
@@ -65,11 +61,11 @@ public bool TryGetSize(string path, out ulong size)
65
61
66
62
private static string GetDriveName ( string path ) => Directory . GetDirectoryRoot ( path ) ;
67
63
68
- private void CreateProvider ( string driveName )
64
+ private ISizeProvider CreateProvider ( )
69
65
{
70
66
var provider = new CachedSizeProvider ( ) ;
71
67
provider . SizeChanged += Provider_SizeChanged ;
72
- providers . Add ( driveName , provider ) ;
68
+ return provider ;
73
69
}
74
70
75
71
private void Provider_SizeChanged ( object ? sender , SizeChangedEventArgs e )
0 commit comments