提交 b437d7f5 编写于 作者: J Jason Malinowski

Don't subscribe to file watching for analyzers until we have to

Before this change we were immediately trying to add file watchers
on the UI thread when we added a new analyzer. This can get delayed
because of slow disks, or because the file watcher service's lock is
held by a background thread. There's no reason to do it until we are
actually observing and loading the analyzer, which typically happens
on a background thread.
上级 b7330c83
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList;
...@@ -31,7 +32,6 @@ public VisualStudioAnalyzer(string fullPath, IVsFileChangeEx fileChangeService, ...@@ -31,7 +32,6 @@ public VisualStudioAnalyzer(string fullPath, IVsFileChangeEx fileChangeService,
_tracker = new FileChangeTracker(fileChangeService, fullPath); _tracker = new FileChangeTracker(fileChangeService, fullPath);
_tracker.UpdatedOnDisk += OnUpdatedOnDisk; _tracker.UpdatedOnDisk += OnUpdatedOnDisk;
_tracker.StartFileChangeListeningAsync(); _tracker.StartFileChangeListeningAsync();
_tracker.EnsureSubscription();
_hostDiagnosticUpdateSource = hostDiagnosticUpdateSource; _hostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
_projectId = projectId; _projectId = projectId;
_workspace = workspace; _workspace = workspace;
...@@ -55,7 +55,9 @@ public AnalyzerReference GetReference() ...@@ -55,7 +55,9 @@ public AnalyzerReference GetReference()
{ {
if (File.Exists(_fullPath)) if (File.Exists(_fullPath))
{ {
_analyzerReference = new AnalyzerFileReference(_fullPath, _loader); // Pass down a custom loader that will ensure we are watching for file changes once we actually load the assembly.
var assemblyLoaderForFileTracker = new AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched(this);
_analyzerReference = new AnalyzerFileReference(_fullPath, assemblyLoaderForFileTracker);
((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError; ((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
} }
else else
...@@ -108,5 +110,30 @@ private void OnUpdatedOnDisk(object sender, EventArgs e) ...@@ -108,5 +110,30 @@ private void OnUpdatedOnDisk(object sender, EventArgs e)
{ {
UpdatedOnDisk?.Invoke(this, EventArgs.Empty); UpdatedOnDisk?.Invoke(this, EventArgs.Empty);
} }
/// <summary>
/// This custom loader just wraps an existing loader, but ensures that we start listening to the file
/// for changes once we've actually looked at the file.
/// </summary>
private class AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched : IAnalyzerAssemblyLoader
{
private readonly VisualStudioAnalyzer _analyzer;
public AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched(VisualStudioAnalyzer analyzer)
{
_analyzer = analyzer;
}
public void AddDependencyLocation(string fullPath)
{
_analyzer._loader.AddDependencyLocation(fullPath);
}
public Assembly LoadFromPath(string fullPath)
{
_analyzer._tracker.EnsureSubscription();
return _analyzer._loader.LoadFromPath(fullPath);
}
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册