Skip to content

Commit c47ac1d

Browse files
authored
Code Quality: Improved loading speed of thumbnails (files-community#14573)
1 parent baa3a2a commit c47ac1d

File tree

1 file changed

+52
-16
lines changed

1 file changed

+52
-16
lines changed

src/Files.App/Data/Models/ItemViewModel.cs

+52-16
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace Files.App.Data.Models
2929
public sealed class ItemViewModel : ObservableObject, IDisposable
3030
{
3131
private readonly SemaphoreSlim enumFolderSemaphore;
32-
private readonly SemaphoreSlim loadPropertiesSemaphore;
32+
private readonly SemaphoreSlim getFileOrFolderSemaphore;
3333
private readonly ConcurrentQueue<(uint Action, string FileName)> operationQueue;
3434
private readonly ConcurrentQueue<uint> gitChangesQueue;
3535
private readonly ConcurrentDictionary<string, bool> itemLoadQueue;
@@ -169,17 +169,57 @@ public async Task SetWorkingDirectoryAsync(string? value)
169169
OnPropertyChanged(nameof(WorkingDirectory));
170170
}
171171

172-
public Task<FilesystemResult<BaseStorageFolder>> GetFolderFromPathAsync(string value)
173-
=> FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(value, workingRoot, currentStorageFolder));
172+
public async Task<FilesystemResult<BaseStorageFolder>> GetFolderFromPathAsync(string value, CancellationToken cancellationToken = default)
173+
{
174+
await getFileOrFolderSemaphore.WaitAsync(cancellationToken);
175+
try
176+
{
177+
return await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(value, workingRoot, currentStorageFolder));
178+
}
179+
finally
180+
{
181+
getFileOrFolderSemaphore.Release();
182+
}
183+
}
174184

175-
public Task<FilesystemResult<BaseStorageFile>> GetFileFromPathAsync(string value)
176-
=> FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(value, workingRoot, currentStorageFolder));
185+
public async Task<FilesystemResult<BaseStorageFile>> GetFileFromPathAsync(string value, CancellationToken cancellationToken = default)
186+
{
187+
await getFileOrFolderSemaphore.WaitAsync(cancellationToken);
188+
try
189+
{
190+
return await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(value, workingRoot, currentStorageFolder));
191+
}
192+
finally
193+
{
194+
getFileOrFolderSemaphore.Release();
195+
}
196+
}
177197

178-
public Task<FilesystemResult<StorageFolderWithPath>> GetFolderWithPathFromPathAsync(string value)
179-
=> FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderWithPathFromPathAsync(value, workingRoot, currentStorageFolder));
198+
public async Task<FilesystemResult<StorageFolderWithPath>> GetFolderWithPathFromPathAsync(string value, CancellationToken cancellationToken = default)
199+
{
200+
await getFileOrFolderSemaphore.WaitAsync(cancellationToken);
201+
try
202+
{
203+
return await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderWithPathFromPathAsync(value, workingRoot, currentStorageFolder));
204+
}
205+
finally
206+
{
207+
getFileOrFolderSemaphore.Release();
208+
}
209+
}
180210

181-
public Task<FilesystemResult<StorageFileWithPath>> GetFileWithPathFromPathAsync(string value)
182-
=> FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileWithPathFromPathAsync(value, workingRoot, currentStorageFolder));
211+
public async Task<FilesystemResult<StorageFileWithPath>> GetFileWithPathFromPathAsync(string value, CancellationToken cancellationToken = default)
212+
{
213+
await getFileOrFolderSemaphore.WaitAsync(cancellationToken);
214+
try
215+
{
216+
return await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileWithPathFromPathAsync(value, workingRoot, currentStorageFolder));
217+
}
218+
finally
219+
{
220+
getFileOrFolderSemaphore.Release();
221+
}
222+
}
183223

184224
private EmptyTextType emptyTextType;
185225
public EmptyTextType EmptyTextType
@@ -443,7 +483,7 @@ public ItemViewModel(LayoutPreferencesManager folderSettingsViewModel)
443483
operationEvent = new AsyncManualResetEvent();
444484
gitChangedEvent = new AsyncManualResetEvent();
445485
enumFolderSemaphore = new SemaphoreSlim(1, 1);
446-
loadPropertiesSemaphore = new SemaphoreSlim(100);
486+
getFileOrFolderSemaphore = new SemaphoreSlim(50);
447487
dispatcherQueue = DispatcherQueue.GetForCurrentThread();
448488

449489
UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent;
@@ -988,8 +1028,6 @@ await Task.Run(async () =>
9881028
ImageSource? groupImage = null;
9891029
GroupedCollection<ListedItem>? gp = null;
9901030

991-
// We use the semaphore to limit the number of concurrent processes because loading properties is a heavy process
992-
await loadPropertiesSemaphore.WaitAsync(cts.Token);
9931031
try
9941032
{
9951033
var isFileTypeGroupMode = folderSettings.DirectoryGroupOption == GroupOption.FileType;
@@ -1005,7 +1043,7 @@ await Task.Run(async () =>
10051043
if (!item.IsShortcut && !item.IsHiddenItem && !FtpHelpers.IsFtpPath(item.ItemPath))
10061044
{
10071045
cts.Token.ThrowIfCancellationRequested();
1008-
matchingStorageFile = await GetFileFromPathAsync(item.ItemPath);
1046+
matchingStorageFile = await GetFileFromPathAsync(item.ItemPath, cts.Token);
10091047
if (matchingStorageFile is not null)
10101048
{
10111049
cts.Token.ThrowIfCancellationRequested();
@@ -1048,7 +1086,7 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
10481086
if (!item.IsShortcut && !item.IsHiddenItem && !FtpHelpers.IsFtpPath(item.ItemPath))
10491087
{
10501088
cts.Token.ThrowIfCancellationRequested();
1051-
BaseStorageFolder matchingStorageFolder = await GetFolderFromPathAsync(item.ItemPath);
1089+
BaseStorageFolder matchingStorageFolder = await GetFolderFromPathAsync(item.ItemPath, cts.Token);
10521090
if (matchingStorageFolder is not null)
10531091
{
10541092
cts.Token.ThrowIfCancellationRequested();
@@ -1107,8 +1145,6 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
11071145
}
11081146
finally
11091147
{
1110-
loadPropertiesSemaphore.Release();
1111-
11121148
if (!wasSyncStatusLoaded)
11131149
{
11141150
cts.Token.ThrowIfCancellationRequested();

0 commit comments

Comments
 (0)