Skip to content

Commit

Permalink
Fix: Fixed crash that would sometimes occur when calculating folder s…
Browse files Browse the repository at this point in the history
…izes (#11012)
  • Loading branch information
jiejasonliu authored Jan 19, 2023
1 parent 7cd9e84 commit dcf7e9d
Showing 1 changed file with 16 additions and 20 deletions.
36 changes: 16 additions & 20 deletions src/Files.Backend/Services/SizeProvider/DrivesSizeProvider.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Threading;
Expand All @@ -9,7 +9,7 @@ namespace Files.Backend.Services.SizeProvider
{
public class DrivesSizeProvider : ISizeProvider
{
private readonly IDictionary<string, ISizeProvider> providers = new Dictionary<string, ISizeProvider>();
private readonly ConcurrentDictionary<string, ISizeProvider> providers = new();

public event EventHandler<SizeChangedEventArgs>? SizeChanged;

Expand All @@ -19,35 +19,31 @@ public async Task CleanAsync()
var oldDriveNames = providers.Keys.Except(currentDrives).ToArray();

foreach (var oldDriveName in oldDriveNames)
{
if (providers.ContainsKey(oldDriveName))
{
providers.Remove(oldDriveName);
}
}
providers.TryRemove(oldDriveName, out _);

foreach (var provider in providers.Values)
{
await provider.CleanAsync();
}
}

public async Task ClearAsync()
{
foreach (var provider in providers)
{
await provider.Value.ClearAsync();
}
foreach (var provider in providers.Values)
await provider.ClearAsync();

providers.Clear();
}

/// <summary>
/// Delegate the update to an instance of CachedSizeProvider.
/// This method is reentrant (thread safe) to avoid having to await each result.
/// </summary>
public Task UpdateAsync(string path, CancellationToken cancellationToken)
{
string driveName = GetDriveName(path);
if (!providers.ContainsKey(driveName))
var provider = providers.GetOrAdd(driveName, (key) =>
{
CreateProvider(driveName);
}
var provider = providers[driveName];
return CreateProvider();
});
return provider.UpdateAsync(path, cancellationToken);
}

Expand All @@ -65,11 +61,11 @@ public bool TryGetSize(string path, out ulong size)

private static string GetDriveName(string path) => Directory.GetDirectoryRoot(path);

private void CreateProvider(string driveName)
private ISizeProvider CreateProvider()
{
var provider = new CachedSizeProvider();
provider.SizeChanged += Provider_SizeChanged;
providers.Add(driveName, provider);
return provider;
}

private void Provider_SizeChanged(object? sender, SizeChangedEventArgs e)
Expand Down

0 comments on commit dcf7e9d

Please sign in to comment.