private async Task <ConcurrentDictionary <Project, ConcurrentQueue <ValueTuple <SymbolAndProjectId, IReferenceFinder> > > > CreateProjectMapAsync( ConcurrentSet <SymbolAndProjectId> symbols) { using (Logger.LogBlock(FunctionId.FindReference_CreateProjectMapAsync, _cancellationToken)) { Func <Project, ConcurrentQueue <ValueTuple <SymbolAndProjectId, IReferenceFinder> > > createQueue = p => new ConcurrentQueue <ValueTuple <SymbolAndProjectId, IReferenceFinder> >(); var projectMap = new ConcurrentDictionary <Project, ConcurrentQueue <ValueTuple <SymbolAndProjectId, IReferenceFinder> > >(); #if PARALLEL Roslyn.Utilities.TaskExtensions.RethrowIncorrectAggregateExceptions(cancellationToken, () => { symbols.AsParallel().WithCancellation(cancellationToken).ForAll(s => { finders.AsParallel().WithCancellation(cancellationToken).ForAll(f => { var projects = f.DetermineProjectsToSearch(s, solution, cancellationToken) ?? SpecializedCollections.EmptyEnumerable <Project>(); foreach (var project in projects.Distinct()) { projectMap.GetOrAdd(project, createQueue).Enqueue(ValueTuple.Create(s, f)); } }); }); }); #else var scope = _documents != null?_documents.Select(d => d.Project).ToImmutableHashSet() : null; foreach (var s in symbols) { foreach (var f in _finders) { _cancellationToken.ThrowIfCancellationRequested(); var projects = await f.DetermineProjectsToSearchAsync(s.Symbol, _solution, scope, _cancellationToken).ConfigureAwait(false) ?? SpecializedCollections.EmptyEnumerable <Project>(); foreach (var project in projects.Distinct().WhereNotNull()) { if (scope == null || scope.Contains(project)) { projectMap.GetOrAdd(project, createQueue).Enqueue(ValueTuple.Create(s, f)); } } } } #endif Contract.ThrowIfTrue(projectMap.Any(kvp => kvp.Value.Count != kvp.Value.ToSet().Count)); return(projectMap); } }
private async Task<ConcurrentDictionary<Project, ConcurrentQueue<ValueTuple<ISymbol, IReferenceFinder>>>> CreateProjectMapAsync( ConcurrentSet<ISymbol> symbols) { using (Logger.LogBlock(FeatureId.FindReference, FunctionId.FindReference_CreateProjectMapAsync, this.cancellationToken)) { Func<Project, ConcurrentQueue<ValueTuple<ISymbol, IReferenceFinder>>> createQueue = p => new ConcurrentQueue<ValueTuple<ISymbol, IReferenceFinder>>(); var projectMap = new ConcurrentDictionary<Project, ConcurrentQueue<ValueTuple<ISymbol, IReferenceFinder>>>(); #if PARALLEL Roslyn.Utilities.TaskExtensions.RethrowIncorrectAggregateExceptions(cancellationToken, () => { symbols.AsParallel().WithCancellation(cancellationToken).ForAll(s => { finders.AsParallel().WithCancellation(cancellationToken).ForAll(f => { var projects = f.DetermineProjectsToSearch(s, solution, cancellationToken) ?? SpecializedCollections.EmptyEnumerable<Project>(); foreach (var project in projects.Distinct()) { projectMap.GetOrAdd(project, createQueue).Enqueue(ValueTuple.Create(s, f)); } }); }); }); #else var scope = this.documents != null ? this.documents.Select(d => d.Project).ToImmutableHashSet() : null; foreach (var s in symbols) { foreach (var f in finders) { this.cancellationToken.ThrowIfCancellationRequested(); var projects = await f.DetermineProjectsToSearchAsync(s, solution, scope, cancellationToken).ConfigureAwait(false) ?? SpecializedCollections.EmptyEnumerable<Project>(); foreach (var project in projects.Distinct().WhereNotNull()) { if (scope == null || scope.Contains(project)) { projectMap.GetOrAdd(project, createQueue).Enqueue(ValueTuple.Create(s, f)); } } } } #endif Contract.ThrowIfTrue(projectMap.Any(kvp => kvp.Value.Count != kvp.Value.ToSet().Count)); return projectMap; } }