未验证 提交 3146b8b4 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #26787 from sharwell/async-package

Convert to AsyncPackage
......@@ -153,4 +153,9 @@
<Rule Id="xUnit2018" Action="None" /> <!-- "do not compare an object's exact type to the abstract class" is a valid assert, but very noisy right now -->
collection.
</Rules>
<Rules AnalyzerId="Microsoft.VisualStudio.SDK.Analyzers" RuleNamespace="Microsoft.VisualStudio.SDK.Analyzers">
<!-- https://github.com/Microsoft/VSSDK-Analyzers/blob/master/doc/index.md -->
<Rule Id="VSSDK001" Action="Warning" /> <!-- Derive from AsyncPackage -->
<Rule Id="VSSDK003" Action="Warning" /> <!-- Support async tool windows -->
</Rules>
</RuleSet>
......@@ -105,6 +105,7 @@
<MicrosoftVisualStudioProjectSystemManagedVersion>2.3.6152103</MicrosoftVisualStudioProjectSystemManagedVersion>
<MicrosoftVisualStudioQualityToolsUnitTestFrameworkVersion>10.0.0.0-alpha</MicrosoftVisualStudioQualityToolsUnitTestFrameworkVersion>
<MicrosoftVisualStudioRemoteControlVersion>14.0.249-master2E2DC10C</MicrosoftVisualStudioRemoteControlVersion>
<MicrosoftVisualStudioSDKAnalyzersVersion>15.7.7</MicrosoftVisualStudioSDKAnalyzersVersion>
<MicrosoftVisualStudioSetupConfigurationInteropVersion>1.15.103</MicrosoftVisualStudioSetupConfigurationInteropVersion>
<MicrosoftVisualStudioSettings140Version>14.3.25407</MicrosoftVisualStudioSettings140Version>
<MicrosoftVisualStudioShell140Version>14.3.25407</MicrosoftVisualStudioShell140Version>
......
......@@ -89,6 +89,8 @@
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Scripting\CSharp\CSharpScripting.csproj">
<IncludeOutputGroupsInVSIX>BuiltProjectOutputGroup</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
......@@ -134,18 +136,22 @@
<ForceIncludeInVSIX>true</ForceIncludeInVSIX>
<AdditionalProperties>TargetFramework=net46</AdditionalProperties>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="EnvDTE" Version="$(EnvDTEVersion)" />
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.Managed" Version="$(MicrosoftVisualStudioProjectSystemManagedVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.8.0" Version="$(MicrosoftVisualStudioShellInterop80Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.9.0" Version="$(MicrosoftVisualStudioShellInterop90Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.10.0" Version="$(MicrosoftVisualStudioShellInterop100Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime" Version="$(MicrosoftVisualStudioShellInterop140DesignTimeVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.15.3.DesignTime" Version="$(MicrosoftVisualStudioShellInterop153DesignTimeVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework" Version="$(MicrosoftVisualStudioShellFrameworkVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Utilities" Version="$(MicrosoftVisualStudioUtilitiesVersion)" />
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildVersion)" />
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCoreVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="$(MicrosoftVisualStudioValidationVersion)" />
<PackageReference Include="System.Threading.Thread" Version="$(SystemThreadingThreadVersion)" />
......
......@@ -4,25 +4,35 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using EnvDTE;
using Microsoft;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace Roslyn.Compilers.Extension
{
[ProvideAutoLoad(UIContextGuids.SolutionExists)]
public sealed class CompilerPackage : Package
[ProvideAutoLoad(UIContextGuids.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
public sealed class CompilerPackage : AsyncPackage
{
public static string RoslynHive = null;
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var reg = (ILocalRegistry2)await GetServiceAsync(typeof(SLocalRegistry)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(reg);
var packagePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string localRegistryRoot;
var reg = (ILocalRegistry2)this.GetService(typeof(SLocalRegistry));
reg.GetLocalRegistryRoot(out localRegistryRoot);
var registryParts = localRegistryRoot.Split('\\');
......@@ -34,7 +44,7 @@ protected override void Initialize()
var hiveName = registryParts[3];
RoslynHive = string.Format(@"{0}.{1}", registryParts[2], registryParts[3]);
WriteMSBuildFiles(packagePath, RoslynHive);
await WriteMSBuildFilesAsync(packagePath, RoslynHive, cancellationToken).ConfigureAwait(true);
try
{
......@@ -48,14 +58,14 @@ protected override void Initialize()
}
}
private void WriteMSBuildFiles(string packagePath, string hiveName)
private async Task WriteMSBuildFilesAsync(string packagePath, string hiveName, CancellationToken cancellationToken)
{
// A map of the file name to the content we need to ensure exists in the file
var filesToWrite = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
// The props we want to be included as early as possible since we want our tasks to be used and
// to ensure our setting of targets path happens early enough
filesToWrite.Add(GetMSBuildRelativePath($@"Imports\Microsoft.Common.props\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.props"),
filesToWrite.Add(await GetMSBuildRelativePathAsync($@"Imports\Microsoft.Common.props\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.props", cancellationToken).ConfigureAwait(true),
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<PropertyGroup Condition=""'$(RoslynHive)' == '{hiveName}'"">
......@@ -80,12 +90,12 @@ private void WriteMSBuildFiles(string packagePath, string hiveName)
</PropertyGroup>
</Project>";
filesToWrite.Add(GetMSBuildRelativePath($@"Microsoft.CSharp.targets\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.targets"), targetsContent);
filesToWrite.Add(GetMSBuildRelativePath($@"Microsoft.VisualBasic.targets\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.targets"), targetsContent);
filesToWrite.Add(await GetMSBuildRelativePathAsync($@"Microsoft.CSharp.targets\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.targets", cancellationToken).ConfigureAwait(true), targetsContent);
filesToWrite.Add(await GetMSBuildRelativePathAsync($@"Microsoft.VisualBasic.targets\ImportBefore\Roslyn.Compilers.Extension.{hiveName}.targets", cancellationToken).ConfigureAwait(true), targetsContent);
// First we want to ensure any Roslyn files with our hive name that we aren't writing -- this is probably
// leftovers from older extensions
var msbuildDirectory = new DirectoryInfo(GetMSBuildPath());
var msbuildDirectory = new DirectoryInfo(await GetMSBuildPathAsync(cancellationToken).ConfigureAwait(true));
if (msbuildDirectory.Exists)
{
foreach (var file in msbuildDirectory.EnumerateFiles($"*Roslyn*{hiveName}*", SearchOption.AllDirectories))
......@@ -131,9 +141,11 @@ private void WriteMSBuildFiles(string packagePath, string hiveName)
}
private string GetMSBuildVersionString()
private async Task<string> GetMSBuildVersionStringAsync(CancellationToken cancellationToken)
{
var dte = (DTE)GetService(typeof(SDTE));
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var dte = (DTE)await GetServiceAsync(typeof(SDTE)).ConfigureAwait(true);
var parts = dte.Version.Split('.');
if (parts.Length == 0)
{
......@@ -156,16 +168,16 @@ private static Exception GetBadVisualStudioVersionException(string version)
return new Exception($"Unrecoginzed Visual Studio Version: {version}");
}
private string GetMSBuildPath()
private async Task<string> GetMSBuildPathAsync(CancellationToken cancellationToken)
{
var version = GetMSBuildVersionString();
var version = await GetMSBuildVersionStringAsync(cancellationToken).ConfigureAwait(true);
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(localAppData, $@"Microsoft\MSBuild\{version}");
}
private string GetMSBuildRelativePath(string relativePath)
private async Task<string> GetMSBuildRelativePathAsync(string relativePath, CancellationToken cancellationToken)
{
return Path.Combine(GetMSBuildPath(), relativePath);
return Path.Combine(await GetMSBuildPathAsync(cancellationToken).ConfigureAwait(true), relativePath);
}
}
}
......@@ -51,4 +51,7 @@
<IncludeOutputGroupsInVSIX>VSIXContainerProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
</ItemGroup>
</Project>
......@@ -100,6 +100,7 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework" Version="$(MicrosoftVisualStudioShellFrameworkVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
</ItemGroup>
......
......@@ -3,19 +3,20 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.VisualStudio.LanguageServices.CSharp.ObjectBrowser;
using Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim;
using Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Utilities;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.CodeAnalysis.Host;
using Microsoft.VisualStudio.LanguageServices.Utilities;
using Task = System.Threading.Tasks.Task;
// NOTE(DustinCa): The EditorFactory registration is in VisualStudioComponents\CSharpPackageRegistration.pkgdef.
// The reason for this is because the ProvideEditorLogicalView does not allow a name value to specified in addition to
......@@ -28,7 +29,7 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService
// TODO(DustinCa): Put all of this in CSharpPackageRegistration.pkgdef rather than using attributes
// (See vsproject\cool\coolpkg\pkg\VCSharp_Proj_System_Reg.pkgdef for an example).
[Guid(Guids.CSharpPackageIdString)]
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[ProvideRoslynVersionRegistration(Guids.CSharpPackageIdString, "Microsoft Visual C#", productNameResourceID: 116, detailsResourceID: 117)]
[ProvideLanguageExtension(typeof(CSharpLanguageService), ".cs")]
[ProvideLanguageService(Guids.CSharpLanguageServiceIdString, "CSharp", languageResourceID: 101, RequestStockColors = true, ShowDropDownOptions = true)]
......@@ -64,24 +65,30 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService
[ProvideAutomationProperties("TextEditor", "CSharp", Guids.TextManagerPackageString, profileNodeLabelId: 101, profileNodeDescriptionId: 106, resourcePackageGuid: Guids.CSharpPackageIdString)]
[ProvideAutomationProperties("TextEditor", "CSharp-Specific", packageGuid: Guids.CSharpPackageIdString, profileNodeLabelId: 104, profileNodeDescriptionId: 105)]
[ProvideService(typeof(CSharpLanguageService), ServiceName = "C# Language Service")]
[ProvideService(typeof(ICSharpTempPECompilerService), ServiceName = "C# TempPE Compiler Service")]
[ProvideService(typeof(CSharpLanguageService), ServiceName = "C# Language Service", IsAsyncQueryable = true)]
[ProvideService(typeof(ICSharpTempPECompilerService), ServiceName = "C# TempPE Compiler Service", IsAsyncQueryable = true)]
internal class CSharpPackage : AbstractPackage<CSharpPackage, CSharpLanguageService>, IVsUserSettingsQuery
{
private ObjectBrowserLibraryManager _libraryManager;
private uint _libraryManagerCookie;
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
try
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
this.RegisterService<ICSharpTempPECompilerService>(() => new TempPECompilerService(this.Workspace.Services.GetService<IMetadataService>()));
this.RegisterService<ICSharpTempPECompilerService>(async ct =>
{
await JoinableTaskFactory.SwitchToMainThreadAsync(ct);
return new TempPECompilerService(this.Workspace.Services.GetService<IMetadataService>());
});
RegisterObjectBrowserLibraryManager();
await RegisterObjectBrowserLibraryManagerAsync(cancellationToken).ConfigureAwait(true);
}
catch (Exception e) when (FatalError.Report(e))
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
}
}
......@@ -93,14 +100,19 @@ protected override VisualStudioWorkspaceImpl CreateWorkspace()
protected override void Dispose(bool disposing)
{
UnregisterObjectBrowserLibraryManager();
if (disposing)
{
JoinableTaskFactory.Run(() => UnregisterObjectBrowserLibraryManagerAsync(CancellationToken.None));
}
base.Dispose(disposing);
}
private void RegisterObjectBrowserLibraryManager()
private async Task RegisterObjectBrowserLibraryManagerAsync(CancellationToken cancellationToken)
{
if (this.GetService(typeof(SVsObjectManager)) is IVsObjectManager2 objectManager)
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
if (await GetServiceAsync(typeof(SVsObjectManager)).ConfigureAwait(true) is IVsObjectManager2 objectManager)
{
_libraryManager = new ObjectBrowserLibraryManager(this);
......@@ -111,11 +123,13 @@ private void RegisterObjectBrowserLibraryManager()
}
}
private void UnregisterObjectBrowserLibraryManager()
private async Task UnregisterObjectBrowserLibraryManagerAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
if (_libraryManagerCookie != 0)
{
if (this.GetService(typeof(SVsObjectManager)) is IVsObjectManager2 objectManager)
if (await GetServiceAsync(typeof(SVsObjectManager)).ConfigureAwait(true) is IVsObjectManager2 objectManager)
{
objectManager.UnregisterLibrary(_libraryManagerCookie);
_libraryManagerCookie = 0;
......
......@@ -11,7 +11,7 @@
namespace Microsoft.VisualStudio.LanguageServices.CSharp.Interactive
{
[Guid(LanguageServiceGuids.CSharpReplPackageIdString)]
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[ProvideMenuResource("Menus.ctmenu", 17)]
[ProvideLanguageExtension(LanguageServiceGuids.CSharpLanguageServiceIdString, ".csx")]
[ProvideInteractiveWindow(
......
......@@ -10,6 +10,8 @@
using System.ComponentModel.Design;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.CodeAnalysis.Editor;
using System.Threading;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Interactive
{
......@@ -44,7 +46,7 @@ internal abstract class AbstractResetInteractiveMenuCommand
.SingleOrDefault();
}
internal void InitializeResetInteractiveFromProjectCommand()
internal async Task InitializeResetInteractiveFromProjectCommandAsync(CancellationToken cancellationToken)
{
var resetInteractiveFromProjectCommand = new OleMenuCommand(
(sender, args) =>
......@@ -67,11 +69,14 @@ internal void InitializeResetInteractiveFromProjectCommand()
resetInteractiveFromProjectCommand.Visible = available;
};
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
_menuCommandService.AddCommand(resetInteractiveFromProjectCommand);
}
private bool GetActiveProject(out EnvDTE.Project project, out FrameworkName frameworkName)
{
ThreadHelper.ThrowIfNotOnUIThread();
project = null;
frameworkName = null;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// 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;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Utilities;
using Microsoft.VisualStudio.Shell;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService
{
internal abstract class AbstractPackage : Package
internal abstract class AbstractPackage : AsyncPackage
{
protected ForegroundThreadAffinitizedObject ForegroundObject;
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
// Assume that we are being initialized on the UI thread at this point, and setup our foreground state
var kind = ForegroundThreadDataInfo.CreateDefault(ForegroundThreadDataKind.ForcedByPackageInitialize);
......@@ -31,14 +32,14 @@ protected override void Initialize()
ForegroundObject = new ForegroundThreadAffinitizedObject();
}
protected void LoadComponentsInUIContextOnceSolutionFullyLoaded()
protected void LoadComponentsInUIContextOnceSolutionFullyLoaded(CancellationToken cancellationToken)
{
ForegroundObject.AssertIsForeground();
if (KnownUIContexts.SolutionExistsAndFullyLoadedContext.IsActive)
{
// if we are already in the right UI context, load it right away
LoadComponentsInUIContext();
LoadComponentsInUIContext(cancellationToken);
}
else
{
......@@ -57,10 +58,10 @@ private void OnSolutionExistsAndFullyLoadedContext(object sender, UIContextChang
KnownUIContexts.SolutionExistsAndFullyLoadedContext.UIContextChanged -= OnSolutionExistsAndFullyLoadedContext;
// load components
LoadComponentsInUIContext();
LoadComponentsInUIContext(CancellationToken.None);
}
}
protected abstract void LoadComponentsInUIContext();
protected abstract void LoadComponentsInUIContext(CancellationToken cancellationToken);
}
}
......@@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Packaging;
using Microsoft.CodeAnalysis.Remote;
......@@ -12,7 +14,9 @@
using Microsoft.VisualStudio.LanguageServices.Packaging;
using Microsoft.VisualStudio.LanguageServices.Remote;
using Microsoft.VisualStudio.LanguageServices.SymbolSearch;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService
{
......@@ -34,24 +38,34 @@ protected AbstractPackage()
{
}
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var shell = (IVsShell)await GetServiceAsync(typeof(SVsShell)).ConfigureAwait(true);
var solution = (IVsSolution)await GetServiceAsync(typeof(SVsSolution)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(shell);
Assumes.Present(solution);
foreach (var editorFactory in CreateEditorFactories())
{
RegisterEditorFactory(editorFactory);
}
RegisterLanguageService(typeof(TLanguageService), () =>
RegisterLanguageService(typeof(TLanguageService), async ct =>
{
await JoinableTaskFactory.SwitchToMainThreadAsync(ct);
// Create the language service, tell it to set itself up, then store it in a field
// so we can notify it that it's time to clean up.
_languageService = CreateLanguageService();
_languageService.Setup();
return _languageService.ComAggregate;
});
var shell = (IVsShell)this.GetService(typeof(SVsShell));
// Okay, this is also a bit strange. We need to get our Interop dll into our process,
// but we're in the GAC. Ask the base Roslyn Package to load, and it will take care of
// it for us.
......@@ -69,7 +83,7 @@ protected override void Initialize()
RegisterMiscellaneousFilesWorkspaceInformation(_miscellaneousFilesWorkspace);
this.Workspace = this.CreateWorkspace();
if (IsInIdeMode(this.Workspace))
if (await IsInIdeModeAsync(this.Workspace, cancellationToken).ConfigureAwait(true))
{
// make sure solution crawler start once everything has been setup.
// this also should be started before any of workspace events start firing
......@@ -78,16 +92,16 @@ protected override void Initialize()
// start remote host
EnableRemoteHostClientService();
Workspace.AdviseSolutionEvents((IVsSolution)GetService(typeof(SVsSolution)));
Workspace.AdviseSolutionEvents(solution);
}
// Ensure services that must be created on the UI thread have been.
HACK_AbstractCreateServicesOnUiThread.CreateServicesOnUIThread(ComponentModel, RoslynLanguageName);
LoadComponentsInUIContextOnceSolutionFullyLoaded();
LoadComponentsInUIContextOnceSolutionFullyLoaded(cancellationToken);
}
protected override void LoadComponentsInUIContext()
protected override void LoadComponentsInUIContext(CancellationToken cancellationToken)
{
ForegroundObject.AssertIsForeground();
......@@ -119,36 +133,39 @@ internal IComponentModel ComponentModel
protected abstract IEnumerable<IVsEditorFactory> CreateEditorFactories();
protected abstract TLanguageService CreateLanguageService();
protected void RegisterService<T>(Func<T> serviceCreator)
protected void RegisterService<T>(Func<CancellationToken, Task<T>> serviceCreator)
{
((IServiceContainer)this).AddService(typeof(T), (container, type) => serviceCreator(), promote: true);
AddService(typeof(T), async (container, cancellationToken, type) => await serviceCreator(cancellationToken).ConfigureAwait(true), promote: true);
}
// When registering a language service, we need to take its ComAggregate wrapper.
protected void RegisterLanguageService(Type t, Func<object> serviceCreator)
protected void RegisterLanguageService(Type t, Func<CancellationToken, Task<object>> serviceCreator)
{
((IServiceContainer)this).AddService(t, (container, type) => serviceCreator(), promote: true);
AddService(t, async (container, cancellationToken, type) => await serviceCreator(cancellationToken).ConfigureAwait(true), promote: true);
}
protected override void Dispose(bool disposing)
{
if (_miscellaneousFilesWorkspace != null)
if (disposing)
{
_miscellaneousFilesWorkspace.StopSolutionCrawler();
}
if (IsInIdeMode(this.Workspace))
{
this.Workspace.StopSolutionCrawler();
DisableRemoteHostClientService();
}
// If we've created the language service then tell it it's time to clean itself up now.
if (_languageService != null)
{
_languageService.TearDown();
_languageService = null;
if (_miscellaneousFilesWorkspace != null)
{
_miscellaneousFilesWorkspace.StopSolutionCrawler();
}
if (ThreadHelper.JoinableTaskFactory.Run(() => IsInIdeModeAsync(this.Workspace, CancellationToken.None)))
{
this.Workspace.StopSolutionCrawler();
DisableRemoteHostClientService();
}
// If we've created the language service then tell it it's time to clean itself up now.
if (_languageService != null)
{
_languageService.TearDown();
_languageService = null;
}
}
base.Dispose(disposing);
......@@ -156,14 +173,16 @@ protected override void Dispose(bool disposing)
protected abstract string RoslynLanguageName { get; }
private bool IsInIdeMode(Workspace workspace)
private async Task<bool> IsInIdeModeAsync(Workspace workspace, CancellationToken cancellationToken)
{
return workspace != null && !IsInCommandLineMode();
return workspace != null && !await IsInCommandLineModeAsync(cancellationToken).ConfigureAwait(true);
}
private bool IsInCommandLineMode()
private async Task<bool> IsInCommandLineModeAsync(CancellationToken cancellationToken)
{
var shell = (IVsShell)this.GetService(typeof(SVsShell));
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var shell = (IVsShell)await GetServiceAsync(typeof(SVsShell)).ConfigureAwait(true);
if (ErrorHandler.Succeeded(shell.GetProperty((int)__VSSPROPID.VSSPROPID_IsInCommandLineMode, out var result)))
{
......
......@@ -4,6 +4,8 @@
using System.ComponentModel.Design;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
......@@ -24,12 +26,13 @@
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Threading;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Setup
{
[Guid(Guids.RoslynPackageIdString)]
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[ProvideMenuResource("Menus.ctmenu", version: 16)]
internal class RoslynPackage : AbstractPackage
{
......@@ -39,9 +42,15 @@ internal class RoslynPackage : AbstractPackage
private RuleSetEventHandler _ruleSetEventHandler;
private IDisposable _solutionEventMonitor;
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
_componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(_componentModel);
FatalError.Handler = FailFast.OnFatalException;
FatalError.NonFatalHandler = WatsonReporter.Report;
......@@ -54,12 +63,11 @@ protected override void Initialize()
var method = compilerFailFast.GetMethod(nameof(FailFast.OnFatalException), BindingFlags.Static | BindingFlags.NonPublic);
property.SetValue(null, Delegate.CreateDelegate(property.PropertyType, method));
var componentModel = (IComponentModel)this.GetService(typeof(SComponentModel));
_workspace = componentModel.GetService<VisualStudioWorkspace>();
_workspace = _componentModel.GetService<VisualStudioWorkspace>();
_workspace.Services.GetService<IExperimentationService>();
// Ensure the options persisters are loaded since we have to fetch options from the shell
componentModel.GetExtensions<IOptionPersister>();
_componentModel.GetExtensions<IOptionPersister>();
RoslynTelemetrySetup.Initialize(this);
......@@ -69,7 +77,7 @@ protected override void Initialize()
InitializeColors();
// load some services that have to be loaded in UI thread
LoadComponentsInUIContextOnceSolutionFullyLoaded();
LoadComponentsInUIContextOnceSolutionFullyLoaded(cancellationToken);
_solutionEventMonitor = new SolutionEventMonitor(_workspace);
}
......@@ -85,7 +93,7 @@ private void InitializeColors()
CodeAnalysisColors.AccentBarColorKey = EnvironmentColors.FileTabInactiveDocumentBorderEdgeBrushKey;
}
protected override void LoadComponentsInUIContext()
protected override void LoadComponentsInUIContext(CancellationToken cancellationToken)
{
// we need to load it as early as possible since we can have errors from
// package from each language very early
......@@ -103,15 +111,17 @@ protected override void LoadComponentsInUIContext()
LoadAnalyzerNodeComponents();
Task.Run(() => LoadComponentsBackgroundAsync());
LoadComponentsBackgroundAsync(cancellationToken).Forget();
}
private async Task LoadComponentsBackgroundAsync()
private async Task LoadComponentsBackgroundAsync(CancellationToken cancellationToken)
{
await TaskScheduler.Default;
// Perf: Initialize the command handlers.
var commandHandlerServiceFactory = this.ComponentModel.GetService<ICommandHandlerServiceFactory>();
commandHandlerServiceFactory.Initialize(ContentTypeNames.RoslynContentType);
LoadInteractiveMenus();
await LoadInteractiveMenusAsync(cancellationToken).ConfigureAwait(true);
this.ComponentModel.GetService<MiscellaneousTodoListTable>();
this.ComponentModel.GetService<MiscellaneousDiagnosticListTable>();
......@@ -120,32 +130,35 @@ private async Task LoadComponentsBackgroundAsync()
var experiments = this.ComponentModel.DefaultExportProvider.GetExportedValues<IExperiment>();
foreach (var experiment in experiments)
{
await experiment.InitializeAsync().ConfigureAwait(false);
await experiment.InitializeAsync().ConfigureAwait(true);
}
}
private void LoadInteractiveMenus()
private async Task LoadInteractiveMenusAsync(CancellationToken cancellationToken)
{
var menuCommandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService));
var monitorSelectionService = (IVsMonitorSelection)this.GetService(typeof(SVsShellMonitorSelection));
// Obtain services and QueryInterface from the main thread
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
new CSharpResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommand();
var menuCommandService = (OleMenuCommandService)await GetServiceAsync(typeof(IMenuCommandService)).ConfigureAwait(true);
var monitorSelectionService = (IVsMonitorSelection)await GetServiceAsync(typeof(SVsShellMonitorSelection)).ConfigureAwait(true);
new VisualBasicResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommand();
// Switch to the background object for constructing commands
await TaskScheduler.Default;
await new CSharpResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommandAsync(cancellationToken)
.ConfigureAwait(true);
await new VisualBasicResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommandAsync(cancellationToken)
.ConfigureAwait(true);
}
internal IComponentModel ComponentModel
{
get
{
if (_componentModel == null)
{
_componentModel = (IComponentModel)GetService(typeof(SComponentModel));
}
return _componentModel;
return _componentModel ?? throw new InvalidOperationException($"Cannot use {nameof(RoslynPackage)}.{nameof(ComponentModel)} prior to initialization.");
}
}
......
// 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;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.IntegrationTest.Setup
{
[Guid("D02DAC01-DDD0-4ECC-8687-79A554852B14")]
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[ProvideMenuResource("Menus.ctmenu", version: 1)]
[ProvideAutoLoad(UIContextGuids80.NoSolution)]
[ProvideAutoLoad(UIContextGuids80.SolutionExists)]
public sealed class IntegrationTestServicePackage : Package
[ProvideAutoLoad(UIContextGuids80.NoSolution, PackageAutoLoadFlags.BackgroundLoad)]
[ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
public sealed class IntegrationTestServicePackage : AsyncPackage
{
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
IntegrationTestServiceCommands.Initialize(this);
}
}
......
......@@ -49,6 +49,8 @@
<ItemGroup>
<Reference Include="System.Design" />
<Reference Include="System.Runtime.Remoting" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="$(MicrosoftDiagnosticsRuntimeVersion)" />
<!--
Required to avoid double write of System.Threading.Tasks.Dataflow.dll caused by both
......@@ -56,7 +58,8 @@
This is tracked by CPS issue https://devdiv.visualstudio.com/DevDiv/_workitems/edit/547065.
Remove this reference once it's fixed.
-->
<PackageReference Include="Microsoft.Tpl.Dataflow" Version="$(MicrosoftTplDataflowVersion)" ExcludeAssets="all"/>
<PackageReference Include="Microsoft.Tpl.Dataflow" Version="$(MicrosoftTplDataflowVersion)" ExcludeAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Test\Diagnostics\Diagnostics.csproj">
......
......@@ -2,24 +2,22 @@
using System;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices.Setup;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using System.Diagnostics;
using Microsoft.VisualStudio.InteractiveWindow;
using System.Reflection;
using Microsoft.VisualStudio.InteractiveWindow.Shell;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.InteractiveWindow;
using Microsoft.VisualStudio.InteractiveWindow.Shell;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Interactive
{
internal abstract partial class VsInteractiveWindowPackage<TVsInteractiveWindowProvider> : Package, IVsToolWindowFactory
internal abstract partial class VsInteractiveWindowPackage<TVsInteractiveWindowProvider> : AsyncPackage, IVsToolWindowFactory
where TVsInteractiveWindowProvider : VsInteractiveWindowProvider
{
protected abstract void InitializeMenuCommands(OleMenuCommandService menuCommandService);
......@@ -30,22 +28,29 @@ internal abstract partial class VsInteractiveWindowPackage<TVsInteractiveWindowP
private IComponentModel _componentModel;
private TVsInteractiveWindowProvider _interactiveWindowProvider;
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var shell = (IVsShell)await GetServiceAsync(typeof(SVsShell)).ConfigureAwait(true);
_componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);
var menuCommandService = (OleMenuCommandService)await GetServiceAsync(typeof(IMenuCommandService)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(shell);
Assumes.Present(_componentModel);
Assumes.Present(menuCommandService);
// Load the Roslyn package so that its FatalError handlers are hooked up.
var shell = (IVsShell)this.GetService(typeof(SVsShell));
shell.LoadPackage(Guids.RoslynPackageId, out var roslynPackage);
// Explicitly set up FatalError handlers for the InteractiveWindowPackage.
SetErrorHandlers(typeof(IInteractiveWindow).Assembly);
SetErrorHandlers(typeof(IVsInteractiveWindow).Assembly);
_componentModel = (IComponentModel)GetService(typeof(SComponentModel));
_interactiveWindowProvider = _componentModel.DefaultExportProvider.GetExportedValue<TVsInteractiveWindowProvider>();
var menuCommandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService));
InitializeMenuCommands(menuCommandService);
}
......
......@@ -50,9 +50,12 @@
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Diagnostics.PerformanceProvider" Version="$(MicrosoftVisualStudioDiagnosticsPerformanceProviderVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
</ItemGroup>
<ItemGroup>
......
......@@ -81,6 +81,7 @@
<!-- All packages that we depend on, either as facades or implementations -->
<PackageReference Include="Microsoft.DiaSymReader" Version="$(MicrosoftDiaSymReaderVersion)" />
<PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="$(MicrosoftDiaSymReaderPortablePdbVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="System.AppContext" Version="$(SystemAppContextVersion)" />
<PackageReference Include="System.Collections" Version="$(SystemCollectionsVersion)" />
<PackageReference Include="System.Collections.Concurrent" Version="$(SystemCollectionsConcurrentVersion)" />
......
......@@ -297,6 +297,9 @@
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="$(MicrosoftDiaSymReaderPortablePdbVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
</ItemGroup>
</Project>
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Runtime.InteropServices
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.ErrorReporting
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.VisualStudio.LanguageServices.CSharp.Options.Formatting
Imports Microsoft.VisualStudio.LanguageServices.Implementation
Imports Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService
......@@ -16,6 +15,7 @@ Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ProjectSystemShim
Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ProjectSystemShim.Interop
Imports Microsoft.VisualStudio.Shell
Imports Microsoft.VisualStudio.Shell.Interop
Imports Task = System.Threading.Tasks.Task
' NOTE(DustinCa): The EditorFactory registration is in VisualStudioComponents\VisualBasicPackageRegistration.pkgdef.
' The reason for this is because the ProvideEditorLogicalView does not allow a name value to specified in addition to
......@@ -38,7 +38,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
' Naming
<Guid(Guids.VisualBasicPackageIdString)>
<PackageRegistration(UseManagedResourcesOnly:=True)>
<PackageRegistration(UseManagedResourcesOnly:=True, AllowsBackgroundLoading:=True)>
<ProvideRoslynVersionRegistration(Guids.VisualBasicPackageIdString, "Microsoft Visual Basic", 113, 114)>
<ProvideLanguageExtension(GetType(VisualBasicLanguageService), ".bas")>
<ProvideLanguageExtension(GetType(VisualBasicLanguageService), ".cls")>
......@@ -55,9 +55,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
<ProvideLanguageEditorOptionPage(GetType(IntelliSenseOptionPage), "Basic", Nothing, "IntelliSense", "#112", 312)>
<ProvideAutomationProperties("TextEditor", "Basic", Guids.TextManagerPackageString, 103, 105, Guids.VisualBasicPackageIdString)>
<ProvideAutomationProperties("TextEditor", "Basic-Specific", Guids.VisualBasicPackageIdString, 104, 106)>
<ProvideService(GetType(VisualBasicLanguageService), ServiceName:="Visual Basic Language Service")>
<ProvideService(GetType(IVbCompilerService), ServiceName:="Visual Basic Project System Shim")>
<ProvideService(GetType(IVbTempPECompilerFactory), ServiceName:="Visual Basic TempPE Compiler Factory Service")>
<ProvideService(GetType(VisualBasicLanguageService), ServiceName:="Visual Basic Language Service", IsAsyncQueryable:=True)>
<ProvideService(GetType(IVbCompilerService), ServiceName:="Visual Basic Project System Shim", IsAsyncQueryable:=True)>
<ProvideService(GetType(IVbTempPECompilerFactory), ServiceName:="Visual Basic TempPE Compiler Factory Service", IsAsyncQueryable:=True)>
Friend Class VisualBasicPackage
Inherits AbstractPackage(Of VisualBasicPackage, VisualBasicLanguageService)
Implements IVbCompilerService
......@@ -84,28 +84,37 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
Return Me.ComponentModel.GetService(Of VisualStudioWorkspaceImpl)
End Function
Protected Overrides Sub Initialize()
Protected Overrides Async Function InitializeAsync(cancellationToken As CancellationToken, progress As IProgress(Of ServiceProgressData)) As Task
Try
MyBase.Initialize()
Await MyBase.InitializeAsync(cancellationToken, progress).ConfigureAwait(True)
Await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken)
RegisterLanguageService(GetType(IVbCompilerService), Function() _comAggregate)
RegisterLanguageService(GetType(IVbCompilerService), Function() Task.FromResult(_comAggregate))
Dim workspace = Me.ComponentModel.GetService(Of VisualStudioWorkspaceImpl)()
RegisterService(Of IVbTempPECompilerFactory)(Function() New TempPECompilerFactory(workspace))
RegisterObjectBrowserLibraryManager()
Catch ex As Exception When FatalError.Report(ex)
RegisterService(Of IVbTempPECompilerFactory)(
Async Function(ct)
Await JoinableTaskFactory.SwitchToMainThreadAsync(ct)
Return New TempPECompilerFactory(workspace)
End Function)
Await RegisterObjectBrowserLibraryManagerAsync(cancellationToken).ConfigureAwait(True)
Catch ex As Exception When FatalError.ReportUnlessCanceled(ex)
End Try
End Sub
End Function
Protected Overrides Sub Dispose(disposing As Boolean)
UnregisterObjectBrowserLibraryManager()
If disposing Then
JoinableTaskFactory.Run(Function() UnregisterObjectBrowserLibraryManagerAsync(CancellationToken.None))
End If
MyBase.Dispose(disposing)
End Sub
Private Sub RegisterObjectBrowserLibraryManager()
Dim objectManager = TryCast(Me.GetService(GetType(SVsObjectManager)), IVsObjectManager2)
Private Async Function RegisterObjectBrowserLibraryManagerAsync(cancellationToken As CancellationToken) As Task
Await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken)
Dim objectManager = TryCast(Await GetServiceAsync(GetType(SVsObjectManager)).ConfigureAwait(True), IVsObjectManager2)
If objectManager IsNot Nothing Then
Me._libraryManager = New ObjectBrowserLibraryManager(Me)
......@@ -113,11 +122,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
Me._libraryManagerCookie = 0
End If
End If
End Sub
End Function
Private Async Function UnregisterObjectBrowserLibraryManagerAsync(cancellationToken As CancellationToken) As Task
Await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken)
Private Sub UnregisterObjectBrowserLibraryManager()
If _libraryManagerCookie <> 0 Then
Dim objectManager = TryCast(Me.GetService(GetType(SVsObjectManager)), IVsObjectManager2)
Dim objectManager = TryCast(Await GetServiceAsync(GetType(SVsObjectManager)).ConfigureAwait(True), IVsObjectManager2)
If objectManager IsNot Nothing Then
objectManager.UnregisterLibrary(Me._libraryManagerCookie)
Me._libraryManagerCookie = 0
......@@ -126,7 +137,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
Me._libraryManager.Dispose()
Me._libraryManager = Nothing
End If
End Sub
End Function
Public Function NeedExport(pageID As String, <Out> ByRef needExportParam As Integer) As Integer Implements IVsUserSettingsQuery.NeedExport
' We need to override MPF's definition of NeedExport since it doesn't know about our automation object
......
......@@ -10,7 +10,7 @@ Imports LanguageServiceGuids = Microsoft.VisualStudio.LanguageServices.Guids
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Interactive
<Guid(LanguageServiceGuids.VisualBasicReplPackageIdString)>
<PackageRegistration(UseManagedResourcesOnly:=True)>
<PackageRegistration(UseManagedResourcesOnly:=True, AllowsBackgroundLoading:=True)>
<ProvideMenuResource("Menus.ctmenu", 17)>
<ProvideInteractiveWindow(
VisualBasicVsInteractiveWindowPackage.IdString,
......
......@@ -12,6 +12,7 @@
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using Microsoft.VisualStudio.LanguageServices.Implementation.Options;
using ThreadHelper = Microsoft.VisualStudio.Shell.ThreadHelper;
namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages
{
......@@ -47,7 +48,7 @@ protected override void OnApply(PageApplyEventArgs e)
SetRoslynLogger(loggerTypes, () => new TraceLogger(options));
// second set RemoteHost options
var client = _remoteHostClientService.TryGetRemoteHostClientAsync(CancellationToken.None).Result;
var client = ThreadHelper.JoinableTaskFactory.Run(() => _remoteHostClientService.TryGetRemoteHostClientAsync(CancellationToken.None));
if (client == null)
{
// Remote host is disabled
......@@ -55,11 +56,11 @@ protected override void OnApply(PageApplyEventArgs e)
}
var functionIds = GetFunctionIds(options).ToList();
var unused = client.TryRunRemoteAsync(
_ = ThreadHelper.JoinableTaskFactory.Run(() => client.TryRunRemoteAsync(
WellKnownRemoteHostServices.RemoteHostService,
nameof(IRemoteHostService.SetLoggingFunctionIds),
new object[] { loggerTypes, functionIds },
CancellationToken.None).Result;
CancellationToken.None));
}
private static IEnumerable<string> GetFunctionIds(Func<FunctionId, bool> options)
......
......@@ -64,10 +64,13 @@
<Reference Include="System.Xaml" />
<Reference Include="System.XML" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="EnvDTE" Version="$(EnvDTEVersion)" />
<PackageReference Include="EnvDTE80" Version="$(EnvDTE80Version)" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Diagnostics.PerformanceProvider" Version="$(MicrosoftVisualStudioDiagnosticsPerformanceProviderVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="$(MicrosoftVisualStudioTextUIVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="$(MicrosoftVisualStudioTextUIWpfVersion)" />
</ItemGroup>
......
......@@ -4,15 +4,16 @@
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft;
using Microsoft.CodeAnalysis.Options;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.LanguageServices.Implementation.Options;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
using Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages;
using Task = System.Threading.Tasks.Task;
namespace Roslyn.VisualStudio.DiagnosticsWindow
{
......@@ -28,7 +29,7 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow
/// </summary>
// This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
// a package.
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
// This attribute is needed to let the shell know that this package exposes some menus.
[ProvideMenuResource("Menus.ctmenu", version: 1)]
// These attributes specify the menu structure to be used in Tools | Options. These are not
......@@ -44,7 +45,7 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow
[Guid(GuidList.guidVisualStudioDiagnosticsWindowPkgString)]
[Description("Roslyn Diagnostics Window")]
[ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
public sealed class VisualStudioDiagnosticsWindowPackage : Package
public sealed class VisualStudioDiagnosticsWindowPackage : AsyncPackage
{
private ForceLowMemoryMode _forceLowMemoryMode;
......@@ -55,6 +56,8 @@ public sealed class VisualStudioDiagnosticsWindowPackage : Package
/// </summary>
private void ShowToolWindow(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
// Get the instance number 0 of this tool window. This window is single instance so this instance
// is actually the only one.
// The last flag is set to true so that if the tool window does not exists it will be created.
......@@ -75,17 +78,23 @@ private void ShowToolWindow(object sender, EventArgs e)
/// Initialization of the package; this method is called right after the package is sited, so this is the place
/// where you can put all the initialization code that rely on services provided by VisualStudio.
/// </summary>
protected override void Initialize()
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var componentModel = (IComponentModel)GetService(typeof(SComponentModel));
var componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);
var menuCommandService = (IMenuCommandService)await GetServiceAsync(typeof(IMenuCommandService)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(componentModel);
Assumes.Present(menuCommandService);
var workspace = componentModel.GetService<VisualStudioWorkspace>();
_forceLowMemoryMode = new ForceLowMemoryMode(workspace.Services.GetService<IOptionService>());
// Add our command handlers for menu (commands must exist in the .vsct file)
if (GetService(typeof(IMenuCommandService)) is OleMenuCommandService mcs)
if (menuCommandService is OleMenuCommandService mcs)
{
// Create the command for the tool window
CommandID toolwndCommandID = new CommandID(GuidList.guidVisualStudioDiagnosticsWindowCmdSet, (int)PkgCmdIDList.CmdIDRoslynDiagnosticWindow);
......
......@@ -142,6 +142,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Security.Cryptography.Algorithms" Version="$(SystemSecurityCryptographyAlgorithmsVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<!-- Even though the VS process includes these, we need to also include them in the VSIX for the interactive host processes -->
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册