@@ -29,7 +29,7 @@ namespace Files.App.Data.Models
29
29
public sealed class ItemViewModel : ObservableObject , IDisposable
30
30
{
31
31
private readonly SemaphoreSlim enumFolderSemaphore ;
32
- private readonly SemaphoreSlim loadPropertiesSemaphore ;
32
+ private readonly SemaphoreSlim getFileOrFolderSemaphore ;
33
33
private readonly ConcurrentQueue < ( uint Action , string FileName ) > operationQueue ;
34
34
private readonly ConcurrentQueue < uint > gitChangesQueue ;
35
35
private readonly ConcurrentDictionary < string , bool > itemLoadQueue ;
@@ -169,17 +169,57 @@ public async Task SetWorkingDirectoryAsync(string? value)
169
169
OnPropertyChanged ( nameof ( WorkingDirectory ) ) ;
170
170
}
171
171
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
+ }
174
184
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
+ }
177
197
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
+ }
180
210
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
+ }
183
223
184
224
private EmptyTextType emptyTextType ;
185
225
public EmptyTextType EmptyTextType
@@ -443,7 +483,7 @@ public ItemViewModel(LayoutPreferencesManager folderSettingsViewModel)
443
483
operationEvent = new AsyncManualResetEvent ( ) ;
444
484
gitChangedEvent = new AsyncManualResetEvent ( ) ;
445
485
enumFolderSemaphore = new SemaphoreSlim ( 1 , 1 ) ;
446
- loadPropertiesSemaphore = new SemaphoreSlim ( 100 ) ;
486
+ getFileOrFolderSemaphore = new SemaphoreSlim ( 50 ) ;
447
487
dispatcherQueue = DispatcherQueue . GetForCurrentThread ( ) ;
448
488
449
489
UserSettingsService . OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent ;
@@ -988,8 +1028,6 @@ await Task.Run(async () =>
988
1028
ImageSource ? groupImage = null ;
989
1029
GroupedCollection < ListedItem > ? gp = null ;
990
1030
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 ) ;
993
1031
try
994
1032
{
995
1033
var isFileTypeGroupMode = folderSettings . DirectoryGroupOption == GroupOption . FileType ;
@@ -1005,7 +1043,7 @@ await Task.Run(async () =>
1005
1043
if ( ! item . IsShortcut && ! item . IsHiddenItem && ! FtpHelpers . IsFtpPath ( item . ItemPath ) )
1006
1044
{
1007
1045
cts . Token . ThrowIfCancellationRequested ( ) ;
1008
- matchingStorageFile = await GetFileFromPathAsync ( item . ItemPath ) ;
1046
+ matchingStorageFile = await GetFileFromPathAsync ( item . ItemPath , cts . Token ) ;
1009
1047
if ( matchingStorageFile is not null )
1010
1048
{
1011
1049
cts . Token . ThrowIfCancellationRequested ( ) ;
@@ -1048,7 +1086,7 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
1048
1086
if ( ! item . IsShortcut && ! item . IsHiddenItem && ! FtpHelpers . IsFtpPath ( item . ItemPath ) )
1049
1087
{
1050
1088
cts . Token . ThrowIfCancellationRequested ( ) ;
1051
- BaseStorageFolder matchingStorageFolder = await GetFolderFromPathAsync ( item . ItemPath ) ;
1089
+ BaseStorageFolder matchingStorageFolder = await GetFolderFromPathAsync ( item . ItemPath , cts . Token ) ;
1052
1090
if ( matchingStorageFolder is not null )
1053
1091
{
1054
1092
cts . Token . ThrowIfCancellationRequested ( ) ;
@@ -1107,8 +1145,6 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
1107
1145
}
1108
1146
finally
1109
1147
{
1110
- loadPropertiesSemaphore . Release ( ) ;
1111
-
1112
1148
if ( ! wasSyncStatusLoaded )
1113
1149
{
1114
1150
cts . Token . ThrowIfCancellationRequested ( ) ;
0 commit comments