public async Task <List <string> > SearchFileAsync(string searchName, float range, int max, CancellationToken cancelToken) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Restart(); List <string> Result = new List <string>(max); if (searchName != string.Empty) { string searchNameLower = searchName.ToLower(); await Task.Run(() => { Algorithms.LevenshteinDistance levenshteinDistance = new LevenshteinDistance(); var Contains = _IndexDictionary .AsParallel() .WithCancellation(cancelToken) .Where(x => x.Key.Contains(searchNameLower)) .OrderBy(x => 1.0 - levenshteinDistance.CalculateNormalizedDistance(searchNameLower, x.Key)) .SelectMany(x => x.Value.ToArray()); Result.AddRange(Contains.Take(max)); if (Result.Count >= max) { return; } if (cancelToken.IsCancellationRequested) { return; } var NotContains = _IndexDictionary .AsParallel() .WithCancellation(cancelToken) .Where(x => !x.Key.Contains(searchNameLower) && (1.0 - levenshteinDistance.CalculateNormalizedDistance(searchName, x.Key)) <= range) .OrderBy(x => 1.0 - levenshteinDistance.CalculateNormalizedDistance(searchNameLower, x.Key)) .SelectMany(x => x.Value.ToArray()); int RemainCapacity = max - Result.Count; Result.AddRange(NotContains.Take(RemainCapacity)); if (cancelToken.IsCancellationRequested) { return; } }); } stopwatch.Stop(); LogStatics.Debug(string.Format("search at {0:F3} s", (float)stopwatch.Elapsed.TotalSeconds)); return(Result); }