提交 ad5b1bb4 编写于 作者: C CyrusNajmabadi

Merge pull request #9663 from CyrusNajmabadi/nugetBackoffMaster

Wait until solution load before we kick off all our nuget work.
......@@ -56,9 +56,6 @@ internal abstract class VisualStudioWorkspaceImpl : VisualStudioWorkspace
private readonly ForegroundThreadAffinitizedObject _foregroundObject = new ForegroundThreadAffinitizedObject();
private PackageInstallerService _packageInstallerService;
private SymbolSearchService _symbolSearchService;
public VisualStudioWorkspaceImpl(
SVsServiceProvider serviceProvider,
WorkspaceBackgroundWork backgroundWork)
......@@ -111,11 +108,6 @@ protected void InitializeStandardVisualStudioWorkspace(SVsServiceProvider servic
// Ensure the options factory services are initialized on the UI thread
this.Services.GetService<IOptionService>();
// Ensure the nuget package services are initialized on the UI thread.
_symbolSearchService = this.Services.GetService<ISymbolSearchService>() as SymbolSearchService;
_packageInstallerService = (PackageInstallerService)this.Services.GetService<IPackageInstallerService>();
_packageInstallerService.Connect(this);
}
/// <summary>NOTE: Call only from derived class constructor</summary>
......@@ -1011,9 +1003,6 @@ internal void StopSolutionCrawler()
protected override void Dispose(bool finalize)
{
_packageInstallerService?.Disconnect(this);
_symbolSearchService?.Dispose();
// workspace is going away. unregister this workspace from work coordinator
StopSolutionCrawler();
......
......@@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Packaging;
......@@ -41,13 +42,9 @@ namespace Microsoft.VisualStudio.LanguageServices.Packaging
internal partial class PackageInstallerService : ForegroundThreadAffinitizedObject, IPackageInstallerService, IVsSearchProviderCallback
{
private readonly object _gate = new object();
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService;
/// <summary>
/// The workspace we're connected to. When we're disconnected this will become 'null'.
/// That's our signal to stop working.
/// </summary>
private VisualStudioWorkspaceImpl _workspace;
private IVsPackageInstallerServices _packageInstallerServices;
private IVsPackageInstaller _packageInstaller;
private IVsPackageUninstaller _packageUninstaller;
......@@ -66,8 +63,10 @@ internal partial class PackageInstallerService : ForegroundThreadAffinitizedObje
[ImportingConstructor]
public PackageInstallerService(
VisualStudioWorkspaceImpl workspace,
IVsEditorAdaptersFactoryService editorAdaptersFactoryService)
{
_workspace = workspace;
_editorAdaptersFactoryService = editorAdaptersFactoryService;
}
......@@ -75,25 +74,25 @@ internal partial class PackageInstallerService : ForegroundThreadAffinitizedObje
public event EventHandler PackageSourcesChanged;
internal void Connect(VisualStudioWorkspaceImpl workspace)
internal void Start()
{
this.AssertIsForeground();
var options = workspace.Options;
var options = _workspace.Options;
if (!options.GetOption(ServiceComponentOnOffOptions.SymbolSearch))
{
return;
}
ConnectWorker(workspace);
StartWorker();
}
// Don't inline this method. The references to nuget types will cause the nuget packages
// to load.
[MethodImpl(MethodImplOptions.NoInlining)]
private void ConnectWorker(VisualStudioWorkspaceImpl workspace)
private void StartWorker()
{
var componentModel = workspace.GetVsService<SComponentModel, IComponentModel>();
var componentModel = _workspace.GetVsService<SComponentModel, IComponentModel>();
_packageInstallerServices = componentModel.GetExtensions<IVsPackageInstallerServices>().FirstOrDefault();
_packageInstaller = componentModel.GetExtensions<IVsPackageInstaller>().FirstOrDefault();
_packageUninstaller = componentModel.GetExtensions<IVsPackageUninstaller>().FirstOrDefault();
......@@ -105,7 +104,6 @@ private void ConnectWorker(VisualStudioWorkspaceImpl workspace)
}
// Start listening to workspace changes.
_workspace = workspace;
_workspace.WorkspaceChanged += OnWorkspaceChanged;
_packageSourceProvider.SourcesChanged += OnSourceProviderSourcesChanged;
......@@ -118,7 +116,7 @@ private void ConnectWorker(VisualStudioWorkspaceImpl workspace)
_packageUninstaller != null &&
_packageSourceProvider != null;
internal void Disconnect(VisualStudioWorkspaceImpl workspace)
internal void Stop()
{
this.AssertIsForeground();
......@@ -127,11 +125,8 @@ internal void Disconnect(VisualStudioWorkspaceImpl workspace)
return;
}
Debug.Assert(workspace == _workspace);
_packageSourceProvider.SourcesChanged -= OnSourceProviderSourcesChanged;
_workspace.WorkspaceChanged -= OnWorkspaceChanged;
_workspace = null;
}
private void OnSourceProviderSourcesChanged(object sender, EventArgs e)
......
......@@ -10,20 +10,24 @@
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Packaging;
using Microsoft.CodeAnalysis.SymbolSearch;
using Microsoft.CodeAnalysis.Versions;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using Microsoft.VisualStudio.LanguageServices.Implementation.Interactive;
using Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.RuleSets;
using Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource;
using Microsoft.VisualStudio.LanguageServices.Packaging;
using Microsoft.VisualStudio.LanguageServices.SymbolSearch;
using Microsoft.VisualStudio.LanguageServices.Utilities;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
using Microsoft.VisualStudio.LanguageServices.Implementation.Interactive;
using static Microsoft.CodeAnalysis.Utilities.ForegroundThreadDataKind;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Setup
{
......@@ -40,6 +44,9 @@ internal class RoslynPackage : Package
private RuleSetEventHandler _ruleSetEventHandler;
private IDisposable _solutionEventMonitor;
private PackageInstallerService _packageInstallerService;
private SymbolSearchService _symbolSearchService;
protected override void Initialize()
{
base.Initialize();
......@@ -161,6 +168,14 @@ private void LoadComponents()
LoadAnalyzerNodeComponents();
// Ensure the nuget package services are initialized after we've loaded
// the solution.
_packageInstallerService = _workspace.Services.GetService<IPackageInstallerService>() as PackageInstallerService;
_symbolSearchService = _workspace.Services.GetService<ISymbolSearchService>() as SymbolSearchService;
_packageInstallerService?.Start();
_symbolSearchService?.Start();
Task.Run(() => LoadComponentsBackground());
}
......@@ -202,6 +217,9 @@ internal IComponentModel ComponentModel
protected override void Dispose(bool disposing)
{
_packageInstallerService?.Stop();
_symbolSearchService?.Stop();
UnregisterFindResultsLibraryManager();
DisposeVisualStudioDocumentTrackingService();
......
......@@ -170,7 +170,6 @@
<Compile Include="SymbolSearch\SymbolSearchService.IOService.cs" />
<Compile Include="SymbolSearch\SymbolSearchService.LogService.cs" />
<Compile Include="SymbolSearch\SymbolSearchService.RemoteControlService.cs" />
<Compile Include="SymbolSearch\SymbolSearchServiceFactory.cs" />
<Compile Include="SymbolSearch\Patching\Delta.cs" />
<Compile Include="RoslynPackage.cs" />
<Compile Include="ServicesVSResources.Designer.cs">
......
......@@ -5,22 +5,21 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Elfie.Model;
using Microsoft.CodeAnalysis.Packaging;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.Internal.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
using static System.FormattableString;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Shared.Options;
using System.Linq;
using System.Collections.Immutable;
namespace Microsoft.VisualStudio.LanguageServices.SymbolSearch
{
......@@ -51,8 +50,6 @@ internal partial class SymbolSearchService
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly CancellationToken _cancellationToken;
private readonly Workspace _workspace;
private readonly ConcurrentDictionary<string, object> _sourceToUpdateSentinel =
new ConcurrentDictionary<string, object>();
......@@ -68,12 +65,6 @@ internal partial class SymbolSearchService
private readonly string _localSettingsDirectory;
private readonly Func<Exception, bool> _reportAndSwallowException;
public void Dispose()
{
// Cancel any existing work.
_cancellationTokenSource.Cancel();
}
private void LogInfo(string text) => _logService.LogInfo(text);
private void LogException(Exception e, string text) => _logService.LogException(e, text);
......
......@@ -3,7 +3,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Composition;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
......@@ -12,14 +12,16 @@
using Microsoft.CodeAnalysis.Elfie.Model.Structures;
using Microsoft.CodeAnalysis.Elfie.Model.Tree;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Packaging;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.SymbolSearch;
using Microsoft.Internal.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.Settings;
using static System.FormattableString;
using VSShell = Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.SymbolSearch
......@@ -31,20 +33,22 @@ namespace Microsoft.VisualStudio.LanguageServices.SymbolSearch
/// This implementation also spawns a task which will attempt to keep that database up to
/// date by downloading patches on a daily basis.
/// </summary>
internal partial class SymbolSearchService :
ForegroundThreadAffinitizedObject,
ISymbolSearchService,
IDisposable
[ExportWorkspaceService(typeof(ISymbolSearchService)), Shared]
internal partial class SymbolSearchService : ForegroundThreadAffinitizedObject, ISymbolSearchService
{
private readonly Workspace _workspace;
private ConcurrentDictionary<string, IAddReferenceDatabaseWrapper> _sourceToDatabase =
new ConcurrentDictionary<string, IAddReferenceDatabaseWrapper>();
private bool _started;
[ImportingConstructor]
public SymbolSearchService(
VSShell.SVsServiceProvider serviceProvider,
Workspace workspace,
IPackageInstallerService installerService)
: this(workspace,
installerService,
VisualStudioWorkspaceImpl workspace,
VSShell.SVsServiceProvider serviceProvider)
: this(workspace,
workspace.Services.GetService<IPackageInstallerService>(),
CreateRemoteControlService(serviceProvider),
new LogService((IVsActivityLog)serviceProvider.GetService(typeof(SVsActivityLog))),
new DelayService(),
......@@ -56,11 +60,6 @@ internal partial class SymbolSearchService :
FatalError.ReportWithoutCrash,
new CancellationTokenSource())
{
installerService.PackageSourcesChanged += OnOptionChanged;
var optionsService = workspace.Services.GetService<IOptionService>();
optionsService.OptionChanged += OnOptionChanged;
OnOptionChanged(this, EventArgs.Empty);
}
private static IRemoteControlService CreateRemoteControlService(VSShell.SVsServiceProvider serviceProvider)
......@@ -112,6 +111,38 @@ private static IRemoteControlService CreateRemoteControlService(VSShell.SVsServi
_cancellationToken = _cancellationTokenSource.Token;
}
internal void Start()
{
var options = _workspace.Options;
if (!options.GetOption(ServiceComponentOnOffOptions.SymbolSearch))
{
return;
}
var optionsService = _workspace.Services.GetService<IOptionService>();
optionsService.OptionChanged += OnOptionChanged;
// Start the whole process once we're connected
_installerService.PackageSourcesChanged += OnOptionChanged;
OnOptionChanged(this, EventArgs.Empty);
_started = true;
}
internal void Stop()
{
if (!_started)
{
return;
}
var optionsService = _workspace.Services.GetService<IOptionService>();
optionsService.OptionChanged -= OnOptionChanged;
_installerService.PackageSourcesChanged -= OnOptionChanged;
// Cancel any existing work.
_cancellationTokenSource.Cancel();
}
public IEnumerable<PackageWithTypeResult> FindPackagesWithType(
string source, string name, int arity, CancellationToken cancellationToken)
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Composition;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Packaging;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.SymbolSearch;
using Roslyn.Utilities;
using VSShell = Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.SymbolSearch
{
[ExportWorkspaceServiceFactory(typeof(ISymbolSearchService), WorkspaceKind.Host), Shared]
internal class SymbolSearchServiceFactory : IWorkspaceServiceFactory
{
private readonly VSShell.SVsServiceProvider _serviceProvider;
[ImportingConstructor]
public SymbolSearchServiceFactory(
VSShell.SVsServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
var options = workspaceServices.Workspace.Options;
if (options.GetOption(ServiceComponentOnOffOptions.SymbolSearch))
{
// Only support package search in vs workspace.
if (workspaceServices.Workspace is VisualStudioWorkspace)
{
return new SymbolSearchService(
_serviceProvider, workspaceServices.Workspace,
workspaceServices.GetService<IPackageInstallerService>());
}
}
return new NullSymbolSearchService();
}
private class NullSymbolSearchService : ISymbolSearchService
{
public IEnumerable<PackageWithTypeResult> FindPackagesWithType(
string source, string name, int arity, CancellationToken cancellationToken)
{
return SpecializedCollections.EmptyEnumerable<PackageWithTypeResult>();
}
public IEnumerable<ReferenceAssemblyWithTypeResult> FindReferenceAssembliesWithType(
string name, int arity, CancellationToken cancellationToken)
{
return SpecializedCollections.EmptyEnumerable<ReferenceAssemblyWithTypeResult>();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册