Add Cancellation token for file system enumeration

This commit is contained in:
张弘韬 2021-01-19 10:08:37 +08:00
parent e9e99ab338
commit d7abae1ab2
2 changed files with 34 additions and 28 deletions

View file

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
{
@ -16,14 +17,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
resultManager = new ResultManager(context);
}
internal List<Result> TopLevelDirectorySearch(Query query, string search)
internal List<Result> TopLevelDirectorySearch(Query query, string search, CancellationToken token)
{
var criteria = ConstructSearchCriteria(search);
if (search.LastIndexOf(Constants.AllFilesFolderSearchWildcard) > search.LastIndexOf(Constants.DirectorySeperator))
return DirectorySearch(SearchOption.AllDirectories, query, search, criteria);
if (search.LastIndexOf(Constants.AllFilesFolderSearchWildcard) >
search.LastIndexOf(Constants.DirectorySeperator))
return DirectorySearch(new EnumerationOptions
{
RecurseSubdirectories = true
}, query, search, criteria, token);
return DirectorySearch(SearchOption.TopDirectoryOnly, query, search, criteria);
return DirectorySearch(null, query, search, criteria, token); // null will be passed as default
}
public string ConstructSearchCriteria(string search)
@ -45,7 +50,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
return incompleteName;
}
private List<Result> DirectorySearch(SearchOption searchOption, Query query, string search, string searchCriteria)
private List<Result> DirectorySearch(EnumerationOptions enumerationOption, Query query, string search,
string searchCriteria, CancellationToken token)
{
var results = new List<Result>();
@ -58,38 +64,38 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
{
var directoryInfo = new System.IO.DirectoryInfo(path);
foreach (var fileSystemInfo in directoryInfo.EnumerateFileSystemInfos(searchCriteria, searchOption))
foreach (var fileSystemInfo in directoryInfo.EnumerateFileSystemInfos(searchCriteria, enumerationOption))
{
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
if (fileSystemInfo is System.IO.DirectoryInfo)
{
folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, fileSystemInfo.FullName, query, true, false));
folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName,
fileSystemInfo.FullName, query, true, false));
}
else
{
fileList.Add(resultManager.CreateFileResult(fileSystemInfo.FullName, query, true, false));
}
if (token.IsCancellationRequested)
return null;
}
}
catch (Exception e)
{
if (e is UnauthorizedAccessException || e is ArgumentException)
{
results.Add(new Result { Title = e.Message, Score = 501 });
if (!(e is ArgumentException)) throw e;
results.Add(new Result {Title = e.Message, Score = 501});
return results;
}
return results;
#if DEBUG // Please investigate and handle error from DirectoryInfo search
throw e;
#else
Log.Exception($"|Flow.Launcher.Plugin.Explorer.DirectoryInfoSearch|Error from performing DirectoryInfoSearch", e);
#endif
#endif
}
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
// Initial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
}
}
}
}

View file

@ -81,12 +81,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return null;
results.AddRange(await TopLevelDirectorySearchBehaviourAsync(WindowsIndexTopLevelFolderSearchAsync,
DirectoryInfoClassSearch,
useIndexSearch,
query,
locationPath,
token).ConfigureAwait(false));
DirectoryInfoClassSearch,
useIndexSearch,
query,
locationPath,
token).ConfigureAwait(false));
return results;
}
@ -109,23 +109,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return actionKeyword == settings.FileContentSearchActionKeyword;
}
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch)
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch, CancellationToken token)
{
var directoryInfoSearch = new DirectoryInfoSearch(context);
return directoryInfoSearch.TopLevelDirectorySearch(query, querySearch);
return directoryInfoSearch.TopLevelDirectorySearch(query, querySearch, token);
}
public async Task<List<Result>> TopLevelDirectorySearchBehaviourAsync(
Func<Query, string, CancellationToken, Task<List<Result>>> windowsIndexSearch,
Func<Query, string, List<Result>> directoryInfoClassSearch,
Func<Query, string, CancellationToken, List<Result>> directoryInfoClassSearch,
bool useIndexSearch,
Query query,
string querySearchString,
CancellationToken token)
{
if (!useIndexSearch)
return directoryInfoClassSearch(query, querySearchString);
return directoryInfoClassSearch(query, querySearchString, token);
return await windowsIndexSearch(query, querySearchString, token);
}