提交 9b8665c9 编写于 作者: C CyrusNajmabadi

Only compute checksums when getting an actual new project instance.

上级 fefcc593
......@@ -165,13 +165,6 @@ public override Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt,
return SpecializedTasks.EmptyTask;
}
if (bodyOpt != null)
{
// This was a method level edit. This can't change the symbol tree info
// for this project. Bail immediately.
return SpecializedTasks.EmptyTask;
}
return UpdateSymbolTreeInfoAsync(document.Project, cancellationToken);
}
......@@ -220,10 +213,17 @@ private async Task UpdateSourceSymbolTreeInfoAsync(Project project, Cancellation
private Task UpdateReferencesAync(Project project, CancellationToken cancellationToken)
{
// Process all metadata references in parallel.
var tasks = project.MetadataReferences.OfType<PortableExecutableReference>()
.Select(r => UpdateReferenceAsync(project, r, cancellationToken))
.ToArray();
// Process all metadata references. If it remote workspace, do this in parallel.
var tasks = new List<Task>();
var isRemoteWorkspace = project.Solution.Workspace.Kind == WorkspaceKind.RemoteWorkspace ||
project.Solution.Workspace.Kind == WorkspaceKind.RemoteTemporaryWorkspace;
foreach (var reference in project.MetadataReferences.OfType<PortableExecutableReference>())
{
tasks.Add(isRemoteWorkspace
? Task.Run(() => UpdateReferenceAsync(project, reference, cancellationToken), cancellationToken)
: UpdateReferenceAsync(project, reference, cancellationToken));
}
return Task.WhenAll(tasks);
}
......
......@@ -151,9 +151,12 @@ private static Metadata GetMetadataNoThrow(PortableExecutableReference reference
{
// We can reuse the index for any given reference as long as it hasn't changed.
// So our checksum is just the checksum for the PEReference itself.
var serializer = new Serializer(solution.Workspace);
var checksum = serializer.CreateChecksum(reference, cancellationToken);
return checksum;
return ChecksumCache.GetOrCreate(reference, _ =>
{
var serializer = new Serializer(solution.Workspace);
var checksum = serializer.CreateChecksum(reference, cancellationToken);
return checksum;
});
}
private static Task<SymbolTreeInfo> TryLoadOrCreateMetadataSymbolTreeInfoAsync(
......
......@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Collections;
......@@ -42,7 +43,22 @@ private static void FreeSymbolMap(MultiDictionary<string, ISymbol> symbolMap)
return result;
}
public static async Task<Checksum> GetSourceSymbolsChecksumAsync(Project project, CancellationToken cancellationToken)
/// <summary>
/// Cache of project to the checksum for it so that we don't have to expensively recompute
/// this each time we get a project.
/// </summary>
private static ConditionalWeakTable<Project, AsyncLazy<Checksum>> s_projectToSourceChecksum =
new ConditionalWeakTable<Project, AsyncLazy<Checksum>>();
public static Task<Checksum> GetSourceSymbolsChecksumAsync(Project project, CancellationToken cancellationToken)
{
var lazy = s_projectToSourceChecksum.GetValue(
project, p => new AsyncLazy<Checksum>(c => ComputeSourceSymbolsChecksumAsync(p, c), cacheResult: true));
return lazy.GetValueAsync(cancellationToken);
}
private static async Task<Checksum> ComputeSourceSymbolsChecksumAsync(Project project, CancellationToken cancellationToken)
{
// The SymbolTree for source is built from the source-symbols from the project's compilation's
// assembly. Specifically, we only get the name, kind and parent/child relationship of all the
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册