From 9aca568584e815bd5e8c4769291673355f3ff9ed Mon Sep 17 00:00:00 2001 From: David Barbet Date: Tue, 10 Sep 2019 12:28:14 -0700 Subject: [PATCH 01/11] Upgrade VS sdk to add new dependency to VS RPC contracts. --- eng/Versions.props | 8 +++++--- .../Def/Microsoft.VisualStudio.LanguageServices.csproj | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 183458165cdb0..d6043745973c2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -78,6 +78,7 @@ 2.1.1 3.13.8 15.8.27812-alpha + 16.4.29305.180 14.3.25407-alpha 1.0.0-beta1-63011-01 8.0.0.0-alpha @@ -127,6 +128,7 @@ 16.2.133-pre 2.3.6152103 14.1.10 + 16.3.35-alpha 16.3.2 1.16.30 16.0.28226-pre @@ -156,7 +158,7 @@ 16.3.13 16.3.13 16.3.29212.169 - 15.3.23 + 15.5.31 2.0.0-rc3-61304-01 4.3.0 2.0.61 @@ -164,7 +166,7 @@ 4.4.0 4.10.1 1.0.1 - 12.0.1 + 12.0.2 4.9.2 4.0.0-rc-2048 4.8.0 @@ -179,7 +181,7 @@ 4.3.0 0.0.4 1.0.21 - 2.1.55 + 2.1.74 4.5.0 1.5.0 0.1.0-alpha-63729-01 diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index 12167e805ba6b..8b00ac8274d61 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -163,6 +163,7 @@ + @@ -186,6 +187,7 @@ + From 51dd7b96abb40e8ef002c51dde5bfa6a40ef4968 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Tue, 10 Sep 2019 14:49:25 -0700 Subject: [PATCH 02/11] Use new output window API for output window logger. --- .../DevDivInsertionFiles.csproj | 1 + .../Loggers/OutputWindowLogger.cs | 105 +++++------------- ...slyn.VisualStudio.DiagnosticsWindow.csproj | 1 + 3 files changed, 27 insertions(+), 80 deletions(-) diff --git a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj index b16ea0fa66fdc..6d65f0470ce8b 100644 --- a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj +++ b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj @@ -108,6 +108,7 @@ <_Dependency Remove="Microsoft.Build"/> <_Dependency Remove="Microsoft.Build.Framework"/> <_Dependency Remove="Microsoft.MSXML"/> + <_Dependency Remove="Microsoft.ServiceHub.Framework" /> <_Dependency Remove="Newtonsoft.Json"/> <_Dependency Remove="stdole"/> <_Dependency Remove="StreamJsonRpc"/> diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs index a86d683dc09ef..3f371aa267f55 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs @@ -2,13 +2,13 @@ using System; using System.Threading; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Options; +using Microsoft.ServiceHub.Framework; using Microsoft.VisualStudio; using Microsoft.VisualStudio.ComponentModelHost; +using Microsoft.VisualStudio.RpcContracts.OutputChannel; using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.CodeAnalysis.Internal.Log { @@ -19,6 +19,9 @@ internal sealed class OutputWindowLogger : ILogger { private readonly Func _loggingChecker; + private readonly ServiceBrokerClient _serviceBrokerClient; + private readonly IThreadingContext _threadingContext; + public OutputWindowLogger() : this((Func)null) { @@ -32,6 +35,18 @@ public OutputWindowLogger(IGlobalOptionService optionService) public OutputWindowLogger(Func loggingChecker) { _loggingChecker = loggingChecker; + + var serviceProvider = ServiceProvider.GlobalProvider; + + var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel)); + Assumes.Present(componentModel); + + var brokeredServiceContainer = (IBrokeredServiceContainer)serviceProvider.GetService(typeof(SVsBrokeredServiceContainer)); + Assumes.Present(brokeredServiceContainer); + var serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); + + _threadingContext = componentModel.GetService(); + _serviceBrokerClient = new ServiceBrokerClient(serviceBroker, _threadingContext.JoinableTaskFactory); } public bool IsEnabled(FunctionId functionId) @@ -41,97 +56,27 @@ public bool IsEnabled(FunctionId functionId) public void Log(FunctionId functionId, LogMessage logMessage) { - OutputPane.WriteLine(string.Format("[{0}] {1} - {2}", Thread.CurrentThread.ManagedThreadId, functionId.ToString(), logMessage.GetMessage())); + WriteLine(string.Format("[{0}] {1} - {2}", Thread.CurrentThread.ManagedThreadId, functionId.ToString(), logMessage.GetMessage())); } public void LogBlockStart(FunctionId functionId, LogMessage logMessage, int uniquePairId, CancellationToken cancellationToken) { - OutputPane.WriteLine(string.Format("[{0}] Start({1}) : {2} - {3}", Thread.CurrentThread.ManagedThreadId, uniquePairId, functionId.ToString(), logMessage.GetMessage())); + WriteLine(string.Format("[{0}] Start({1}) : {2} - {3}", Thread.CurrentThread.ManagedThreadId, uniquePairId, functionId.ToString(), logMessage.GetMessage())); } public void LogBlockEnd(FunctionId functionId, LogMessage logMessage, int uniquePairId, int delta, CancellationToken cancellationToken) { var functionString = functionId.ToString() + (cancellationToken.IsCancellationRequested ? " Canceled" : string.Empty); - OutputPane.WriteLine(string.Format("[{0}] End({1}) : [{2}ms] {3}", Thread.CurrentThread.ManagedThreadId, uniquePairId, delta, functionString)); + WriteLine(string.Format("[{0}] End({1}) : [{2}ms] {3}", Thread.CurrentThread.ManagedThreadId, uniquePairId, delta, functionString)); } - private class OutputPane + private void WriteLine(string value) { - private static readonly Guid s_outputPaneGuid = new Guid("BBAFF416-4AF5-41F2-9F93-91F283E43C3B"); - - public static readonly OutputPane s_instance = new OutputPane(); - - private readonly IServiceProvider _serviceProvider; - private readonly IThreadingContext _threadingContext; - - public static void WriteLine(string value) - { - s_instance.WriteLineInternal(value); - } - - public OutputPane() - { - _serviceProvider = ServiceProvider.GlobalProvider; - - var componentModel = (IComponentModel)_serviceProvider.GetService(typeof(SComponentModel)); - _threadingContext = componentModel.GetService(); - } - - private IVsOutputWindowPane _doNotAccessDirectlyOutputPane; - - private void WriteLineInternal(string value) - { - var pane = GetPane(); - if (pane == null) - { - return; - } - - pane.OutputStringThreadSafe(value + Environment.NewLine); - } - - private IVsOutputWindowPane GetPane() + _threadingContext.JoinableTaskFactory.RunAsync(async () => { - if (_doNotAccessDirectlyOutputPane == null) - { - _threadingContext.JoinableTaskFactory.Run(async () => - { - await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); - - if (_doNotAccessDirectlyOutputPane != null) - { - // check whether other one already initialized output window. - // the output API already handle double initialization, so this is just quick bail - // rather than any functional issue - return; - } - - var outputWindow = (IVsOutputWindow)_serviceProvider.GetService(typeof(SVsOutputWindow)); - - // this should bring outout window to the front - _doNotAccessDirectlyOutputPane = CreateOutputPane(outputWindow); - }); - } - - return _doNotAccessDirectlyOutputPane; - } - - private IVsOutputWindowPane CreateOutputPane(IVsOutputWindow outputWindow) - { - _threadingContext.ThrowIfNotOnUIThread(); - - // Try to get the workspace pane if it has already been registered - var workspacePaneGuid = s_outputPaneGuid; - - // If the pane has already been created, CreatePane returns it - if (ErrorHandler.Succeeded(outputWindow.CreatePane(ref workspacePaneGuid, "Roslyn Logger Output", fInitVisible: 1, fClearWithSolution: 1)) && - ErrorHandler.Succeeded(outputWindow.GetPane(ref workspacePaneGuid, out var pane))) - { - return pane; - } - - return null; - } + using var outputChannelStore = await _serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); + await outputChannelStore.Proxy.WriteLineAsync("Roslyn Logger Output", value).ConfigureAwait(false); + }); } } } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj index c07c2e3d42de3..d60631b12a0c1 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj @@ -60,6 +60,7 @@ + From 41e888bc9139c62e2bfee73d7b3d6b2ac4596db6 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 11 Sep 2019 15:54:53 -0700 Subject: [PATCH 03/11] Use new output winodw API for workspace failed events. --- .../Workspace/WorkspaceFailureOutputPane.cs | 114 ------------------ src/VisualStudio/Core/Def/RoslynPackage.cs | 22 +++- 2 files changed, 20 insertions(+), 116 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Implementation/Workspace/WorkspaceFailureOutputPane.cs diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/WorkspaceFailureOutputPane.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/WorkspaceFailureOutputPane.cs deleted file mode 100644 index ffc4ff581476a..0000000000000 --- a/src/VisualStudio/Core/Def/Implementation/Workspace/WorkspaceFailureOutputPane.cs +++ /dev/null @@ -1,114 +0,0 @@ -// 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 Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.VisualStudio.Shell.Interop; - -namespace Microsoft.VisualStudio.LanguageServices -{ - using Workspace = Microsoft.CodeAnalysis.Workspace; - - internal class WorkspaceFailureOutputPane : ForegroundThreadAffinitizedObject - { - private static readonly Guid s_workspacePaneGuid = new Guid("53D7CABD-085E-46AF-ACCA-EF5A640641CA"); - - private readonly IServiceProvider _serviceProvider; - private readonly Workspace _workspace; - - public WorkspaceFailureOutputPane(IThreadingContext threadingContext, IServiceProvider serviceProvider, Workspace workspace) - : base(threadingContext) - { - _serviceProvider = serviceProvider; - _workspace = workspace; - _workspace.WorkspaceFailed += OnWorkspaceFailed; - } - - private void OnWorkspaceFailed(object sender, WorkspaceDiagnosticEventArgs e) - { - InvokeBelowInputPriorityAsync(() => - { - this.OutputPaneOpt?.OutputString(e.Diagnostic.ToString() + Environment.NewLine); - }); - } - - private IVsOutputWindowPane _doNotAccessDirectlyOutputPane; - - private IVsOutputWindowPane OutputPaneOpt - { - get - { - AssertIsForeground(); - - if (_doNotAccessDirectlyOutputPane == null) - { - var outputWindow = (IVsOutputWindow)_serviceProvider.GetService(typeof(SVsOutputWindow)); - - // This may run during the shutdown of Visual Studio and so we must be ready for the service - // not being available. - if (outputWindow == null) - { - return null; - } - - // Output Window panes have two states; initialized and active. The former is used to indicate that the pane - // can be made active ("selected") by the user, the latter indicates that the pane is currently active. - // There's no way to only initialize a pane without also making it active so we remember the last active pane - // and reactivate it after we've created ourselves to avoid stealing focus away from it. - var lastActivePane = GetActivePane(outputWindow); - - _doNotAccessDirectlyOutputPane = CreateOutputPane(outputWindow); - - if (lastActivePane != Guid.Empty) - { - ActivatePane(outputWindow, lastActivePane); - } - } - - return _doNotAccessDirectlyOutputPane; - } - } - - private IVsOutputWindowPane CreateOutputPane(IVsOutputWindow outputWindow) - { - AssertIsForeground(); - - // Try to get the workspace pane if it has already been registered - var workspacePaneGuid = s_workspacePaneGuid; - - // If the pane has already been created, CreatePane returns it - if (ErrorHandler.Succeeded(outputWindow.CreatePane(ref workspacePaneGuid, ServicesVSResources.IntelliSense, fInitVisible: 1, fClearWithSolution: 1)) && - ErrorHandler.Succeeded(outputWindow.GetPane(ref workspacePaneGuid, out var pane))) - { - return pane; - } - - return null; - } - - private Guid GetActivePane(IVsOutputWindow outputWindow) - { - AssertIsForeground(); - - if (outputWindow is IVsOutputWindow2 outputWindow2) - { - if (ErrorHandler.Succeeded(outputWindow2.GetActivePaneGUID(out var activePaneGuid))) - { - return activePaneGuid; - } - } - - return Guid.Empty; - } - - private void ActivatePane(IVsOutputWindow outputWindow, Guid paneGuid) - { - AssertIsForeground(); - - if (ErrorHandler.Succeeded(outputWindow.GetPane(ref paneGuid, out var pane))) - { - pane.Activate(); - } - } - } -} diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 14a65e3c96749..82709d0c9067e 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Notification; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Versions; +using Microsoft.ServiceHub.Framework; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices.Experimentation; using Microsoft.VisualStudio.LanguageServices.Implementation; @@ -28,6 +29,7 @@ using Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; using Microsoft.VisualStudio.LanguageServices.Telemetry; using Microsoft.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.RpcContracts.OutputChannel; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.TaskStatusCenter; @@ -43,7 +45,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Setup internal class RoslynPackage : AbstractPackage { private VisualStudioWorkspace _workspace; - private WorkspaceFailureOutputPane _outputPane; private IComponentModel _componentModel; private RuleSetEventHandler _ruleSetEventHandler; private IDisposable _solutionEventMonitor; @@ -78,7 +79,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke RoslynTelemetrySetup.Initialize(this); // set workspace output pane - _outputPane = new WorkspaceFailureOutputPane(_componentModel.GetService(), this, _workspace); + await InitializeWorkspaceFailureOutputWindow().ConfigureAwait(true); InitializeColors(); @@ -90,6 +91,23 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke TrackBulkFileOperations(); } + private async Task InitializeWorkspaceFailureOutputWindow() + { + var threadingContext = _componentModel.GetService(); + var brokeredServiceContainer = await this.GetServiceAsync().ConfigureAwait(false); + Assumes.Present(brokeredServiceContainer); + var serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); + var serviceBrokerClient = new ServiceBrokerClient(serviceBroker, threadingContext.JoinableTaskFactory); + +#pragma warning disable VSTHRD101 // Avoid unsupported async delegates + _workspace.WorkspaceFailed += async (sender, eventArgs) => + { + using var outputChannelStore = await serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); + await outputChannelStore.Proxy.WriteLineAsync(ServicesVSResources.IntelliSense, eventArgs.Diagnostic.ToString()).ConfigureAwait(false); + }; +#pragma warning restore VSTHRD101 // Avoid unsupported async delegates + } + private void InitializeColors() { // Use VS color keys in order to support theming. From 233c95254866f6f01c96c64acffadb53e327ff97 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 12 Sep 2019 11:46:03 -0700 Subject: [PATCH 04/11] Update package reference to use later version of servicehub framework. --- .../Core/Def/Microsoft.VisualStudio.LanguageServices.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index 8b00ac8274d61..6f73a9b5233cb 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -164,6 +164,7 @@ + From f77ea74cfc32906d5effe6d54bdea657fd81001b Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 12 Sep 2019 12:00:00 -0700 Subject: [PATCH 05/11] Pass in brokered service container as parameter. --- .../Loggers/OutputWindowLogger.cs | 20 ++----------------- .../OptionPages/PerformanceLoggersPage.cs | 10 +++++++--- .../VisualStudioDiagnosticsWindowPackage.cs | 4 +++- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs index 3f371aa267f55..66dd31fa9f044 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs @@ -22,30 +22,14 @@ internal sealed class OutputWindowLogger : ILogger private readonly ServiceBrokerClient _serviceBrokerClient; private readonly IThreadingContext _threadingContext; - public OutputWindowLogger() - : this((Func)null) - { - } - - public OutputWindowLogger(IGlobalOptionService optionService) - : this(Logger.GetLoggingChecker(optionService)) - { - } - - public OutputWindowLogger(Func loggingChecker) + public OutputWindowLogger(Func loggingChecker, IThreadingContext threadingContext, IBrokeredServiceContainer brokeredServiceContainer) { _loggingChecker = loggingChecker; - var serviceProvider = ServiceProvider.GlobalProvider; - - var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel)); - Assumes.Present(componentModel); - - var brokeredServiceContainer = (IBrokeredServiceContainer)serviceProvider.GetService(typeof(SVsBrokeredServiceContainer)); Assumes.Present(brokeredServiceContainer); var serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); - _threadingContext = componentModel.GetService(); + _threadingContext = threadingContext; _serviceBrokerClient = new ServiceBrokerClient(serviceBroker, _threadingContext.JoinableTaskFactory); } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs index 1864bc1f63f96..b5a1aa6cca81e 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs @@ -13,6 +13,7 @@ using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.LanguageServices.Implementation; using Microsoft.VisualStudio.LanguageServices.Implementation.Options; +using Microsoft.VisualStudio.Shell; namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages { @@ -22,12 +23,14 @@ internal class PerformanceLoggersPage : AbstractOptionPage private IGlobalOptionService _optionService; private IThreadingContext _threadingContext; private IRemoteHostClientService _remoteService; + private IBrokeredServiceContainer _brokeredServiceContainer; protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider, OptionStore optionStore) { if (_optionService == null) { var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel)); + _brokeredServiceContainer = (IBrokeredServiceContainer)serviceProvider.GetService(typeof(SVsBrokeredServiceContainer)); _optionService = componentModel.GetService(); _threadingContext = componentModel.GetService(); @@ -43,10 +46,11 @@ protected override void OnApply(PageApplyEventArgs e) { base.OnApply(e); - SetLoggers(_optionService, _threadingContext, _remoteService); + SetLoggers(_optionService, _threadingContext, _remoteService, _brokeredServiceContainer); } - public static void SetLoggers(IGlobalOptionService optionService, IThreadingContext threadingContext, IRemoteHostClientService remoteService) + public static void SetLoggers(IGlobalOptionService optionService, IThreadingContext threadingContext, + IRemoteHostClientService remoteService, IBrokeredServiceContainer brokeredServiceContainer) { var loggerTypes = GetLoggerTypes(optionService).ToList(); @@ -55,7 +59,7 @@ public static void SetLoggers(IGlobalOptionService optionService, IThreadingCont SetRoslynLogger(loggerTypes, () => new EtwLogger(options)); SetRoslynLogger(loggerTypes, () => new TraceLogger(options)); - SetRoslynLogger(loggerTypes, () => new OutputWindowLogger(options)); + SetRoslynLogger(loggerTypes, () => new OutputWindowLogger(options, threadingContext, brokeredServiceContainer)); // second set RemoteHost options var client = threadingContext.JoinableTaskFactory.Run(() => remoteService.TryGetRemoteHostClientAsync(CancellationToken.None)); diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs index 52aa23790ce64..1cfb648ee8960 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs @@ -110,7 +110,9 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke var optionService = componentModel.GetService(); var remoteService = workspace.Services.GetService(); - PerformanceLoggersPage.SetLoggers(optionService, _threadingContext, remoteService); + var brokeredServiceContainer = (IBrokeredServiceContainer)await GetServiceAsync(typeof(SVsBrokeredServiceContainer)).ConfigureAwait(true); + + PerformanceLoggersPage.SetLoggers(optionService, _threadingContext, remoteService, brokeredServiceContainer); } #endregion From 6606d5cb36b579d45b515ed9cfccb5adef79760b Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 12 Sep 2019 12:43:20 -0700 Subject: [PATCH 06/11] Rename outputwindow method to async. --- src/VisualStudio/Core/Def/RoslynPackage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 82709d0c9067e..a407ab1c2be17 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -79,7 +79,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke RoslynTelemetrySetup.Initialize(this); // set workspace output pane - await InitializeWorkspaceFailureOutputWindow().ConfigureAwait(true); + await InitializeWorkspaceFailureOutputWindowAsync().ConfigureAwait(true); InitializeColors(); @@ -91,7 +91,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke TrackBulkFileOperations(); } - private async Task InitializeWorkspaceFailureOutputWindow() + private async Task InitializeWorkspaceFailureOutputWindowAsync() { var threadingContext = _componentModel.GetService(); var brokeredServiceContainer = await this.GetServiceAsync().ConfigureAwait(false); From acd328ae6caf37095d04138c2e1b32c3c97c8a70 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 12 Sep 2019 13:16:10 -0700 Subject: [PATCH 07/11] Fix version numbers for Rpc contracts dependencies. --- eng/Versions.props | 3 ++- .../Core/Def/Microsoft.VisualStudio.LanguageServices.csproj | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index d6043745973c2..595c5dbfcf883 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -78,7 +78,7 @@ 2.1.1 3.13.8 15.8.27812-alpha - 16.4.29305.180 + 16.4.29305.180 14.3.25407-alpha 1.0.0-beta1-63011-01 8.0.0.0-alpha @@ -92,6 +92,7 @@ 0.1.0 0.1.2-dev 2.0.48 + 2.0.84 10.1.0 15.8.27812-alpha 15.8.27812-alpha diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index 6f73a9b5233cb..c4e2f54f4a4af 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -163,9 +163,9 @@ - - + + From aa27e0ead739ad348844ba299e843e17340b3295 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 12 Sep 2019 13:53:31 -0700 Subject: [PATCH 08/11] Fix RPC contracts version parameter name. --- eng/Versions.props | 2 +- .../Core/Def/Microsoft.VisualStudio.LanguageServices.csproj | 2 +- .../Roslyn.VisualStudio.DiagnosticsWindow.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 595c5dbfcf883..da204712fc2d0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -129,7 +129,7 @@ 16.2.133-pre 2.3.6152103 14.1.10 - 16.3.35-alpha + 16.3.35-alpha 16.3.2 1.16.30 16.0.28226-pre diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index c4e2f54f4a4af..7c0cf9882002c 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -188,7 +188,7 @@ - + diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj index d60631b12a0c1..e341f4d83f084 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Roslyn.VisualStudio.DiagnosticsWindow.csproj @@ -60,7 +60,7 @@ - + From bd754025359853be09ca98c072634e0880142f53 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Fri, 13 Sep 2019 14:55:32 -0700 Subject: [PATCH 09/11] Track async output window calls with async listener. --- src/VisualStudio/Core/Def/RoslynPackage.cs | 16 +++++++++++----- .../Loggers/OutputWindowLogger.cs | 14 +++++++++----- .../OptionPages/PerformanceLoggersPage.cs | 10 +++++++--- .../VisualStudioDiagnosticsWindowPackage.cs | 4 +++- .../Shared/TestHooks/FeatureAttribute_Names.cs | 2 ++ 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index a407ab1c2be17..06a87a1dcb87d 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.Logging; using Microsoft.CodeAnalysis.Notification; using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Versions; using Microsoft.ServiceHub.Framework; using Microsoft.VisualStudio.ComponentModelHost; @@ -94,18 +95,23 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke private async Task InitializeWorkspaceFailureOutputWindowAsync() { var threadingContext = _componentModel.GetService(); + var asyncListenerProvider = _componentModel.GetService(); + var asyncListener = asyncListenerProvider.GetListener(FeatureAttribute.WorkspaceFailureLogger); + var brokeredServiceContainer = await this.GetServiceAsync().ConfigureAwait(false); Assumes.Present(brokeredServiceContainer); var serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); var serviceBrokerClient = new ServiceBrokerClient(serviceBroker, threadingContext.JoinableTaskFactory); -#pragma warning disable VSTHRD101 // Avoid unsupported async delegates - _workspace.WorkspaceFailed += async (sender, eventArgs) => + _workspace.WorkspaceFailed += (sender, eventArgs) => { - using var outputChannelStore = await serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); - await outputChannelStore.Proxy.WriteLineAsync(ServicesVSResources.IntelliSense, eventArgs.Diagnostic.ToString()).ConfigureAwait(false); + var asyncToken = asyncListener.BeginAsyncOperation(nameof(InitializeWorkspaceFailureOutputWindowAsync)); + Task.Run(async () => + { + using var outputChannelStore = await serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); + await outputChannelStore.Proxy.WriteLineAsync(ServicesVSResources.IntelliSense, eventArgs.Diagnostic.ToString()).ConfigureAwait(false); + }); }; -#pragma warning restore VSTHRD101 // Avoid unsupported async delegates } private void InitializeColors() diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs index 66dd31fa9f044..055b387c80a78 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/Loggers/OutputWindowLogger.cs @@ -3,12 +3,12 @@ using System; using System.Threading; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.ServiceHub.Framework; using Microsoft.VisualStudio; -using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.RpcContracts.OutputChannel; using Microsoft.VisualStudio.Shell; +using Task = System.Threading.Tasks.Task; namespace Microsoft.CodeAnalysis.Internal.Log { @@ -19,16 +19,19 @@ internal sealed class OutputWindowLogger : ILogger { private readonly Func _loggingChecker; + private readonly IAsynchronousOperationListener _asyncListener; private readonly ServiceBrokerClient _serviceBrokerClient; private readonly IThreadingContext _threadingContext; - public OutputWindowLogger(Func loggingChecker, IThreadingContext threadingContext, IBrokeredServiceContainer brokeredServiceContainer) + public OutputWindowLogger(Func loggingChecker, IAsynchronousOperationListenerProvider asyncListenerProvider, + IThreadingContext threadingContext, IBrokeredServiceContainer brokeredServiceContainer) { _loggingChecker = loggingChecker; Assumes.Present(brokeredServiceContainer); var serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); + _asyncListener = asyncListenerProvider.GetListener(FeatureAttribute.OutputWindowLogger); _threadingContext = threadingContext; _serviceBrokerClient = new ServiceBrokerClient(serviceBroker, _threadingContext.JoinableTaskFactory); } @@ -56,11 +59,12 @@ public void LogBlockEnd(FunctionId functionId, LogMessage logMessage, int unique private void WriteLine(string value) { - _threadingContext.JoinableTaskFactory.RunAsync(async () => + var asyncToken = _asyncListener.BeginAsyncOperation(nameof(WriteLine)); + Task.Run(async () => { using var outputChannelStore = await _serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); await outputChannelStore.Proxy.WriteLineAsync("Roslyn Logger Output", value).ConfigureAwait(false); - }); + }).CompletesAsyncOperation(asyncToken); } } } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs index b5a1aa6cca81e..ea5756ba914f0 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.LanguageServices.Implementation; @@ -20,6 +21,7 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages [Guid(Guids.RoslynOptionPagePerformanceLoggersIdString)] internal class PerformanceLoggersPage : AbstractOptionPage { + private IAsynchronousOperationListenerProvider _asyncListenerProvider; private IGlobalOptionService _optionService; private IThreadingContext _threadingContext; private IRemoteHostClientService _remoteService; @@ -30,6 +32,8 @@ protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider s if (_optionService == null) { var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel)); + _asyncListenerProvider = componentModel.GetService(); + _brokeredServiceContainer = (IBrokeredServiceContainer)serviceProvider.GetService(typeof(SVsBrokeredServiceContainer)); _optionService = componentModel.GetService(); @@ -46,10 +50,10 @@ protected override void OnApply(PageApplyEventArgs e) { base.OnApply(e); - SetLoggers(_optionService, _threadingContext, _remoteService, _brokeredServiceContainer); + SetLoggers(_optionService, _asyncListenerProvider, _threadingContext, _remoteService, _brokeredServiceContainer); } - public static void SetLoggers(IGlobalOptionService optionService, IThreadingContext threadingContext, + public static void SetLoggers(IGlobalOptionService optionService, IAsynchronousOperationListenerProvider asyncListenerProvider, IThreadingContext threadingContext, IRemoteHostClientService remoteService, IBrokeredServiceContainer brokeredServiceContainer) { var loggerTypes = GetLoggerTypes(optionService).ToList(); @@ -59,7 +63,7 @@ public static void SetLoggers(IGlobalOptionService optionService, IThreadingCont SetRoslynLogger(loggerTypes, () => new EtwLogger(options)); SetRoslynLogger(loggerTypes, () => new TraceLogger(options)); - SetRoslynLogger(loggerTypes, () => new OutputWindowLogger(options, threadingContext, brokeredServiceContainer)); + SetRoslynLogger(loggerTypes, () => new OutputWindowLogger(options, asyncListenerProvider, threadingContext, brokeredServiceContainer)); // second set RemoteHost options var client = threadingContext.JoinableTaskFactory.Run(() => remoteService.TryGetRemoteHostClientAsync(CancellationToken.None)); diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs index 1cfb648ee8960..b6ebe1ecbf387 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.LanguageServices.Implementation.Options; @@ -111,8 +112,9 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke var remoteService = workspace.Services.GetService(); var brokeredServiceContainer = (IBrokeredServiceContainer)await GetServiceAsync(typeof(SVsBrokeredServiceContainer)).ConfigureAwait(true); + var asyncOperationListenerProvider = componentModel.GetService(); - PerformanceLoggersPage.SetLoggers(optionService, _threadingContext, remoteService, brokeredServiceContainer); + PerformanceLoggersPage.SetLoggers(optionService, asyncOperationListenerProvider, _threadingContext, remoteService, brokeredServiceContainer); } #endregion diff --git a/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute_Names.cs b/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute_Names.cs index 59d5f24ac2b49..c1eb12ae3a0c0 100644 --- a/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute_Names.cs +++ b/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute_Names.cs @@ -28,6 +28,7 @@ internal partial class FeatureAttribute public const string NavigateTo = nameof(NavigateTo); public const string NavigationBar = nameof(NavigationBar); public const string Outlining = nameof(Outlining); + public const string OutputWindowLogger = nameof(OutputWindowLogger); public const string QuickInfo = nameof(QuickInfo); public const string ReferenceHighlighting = nameof(ReferenceHighlighting); public const string Rename = nameof(Rename); @@ -40,5 +41,6 @@ internal partial class FeatureAttribute public const string TodoCommentList = nameof(TodoCommentList); public const string LanguageServerWorkspaceSymbolSearch = nameof(LanguageServerWorkspaceSymbolSearch); public const string Workspace = nameof(Workspace); + public const string WorkspaceFailureLogger = nameof(WorkspaceFailureLogger); } } From 60460b0e9f623ab2bd2a4dccd11a4ed796f71cea Mon Sep 17 00:00:00 2001 From: David Barbet Date: Fri, 13 Sep 2019 15:29:16 -0700 Subject: [PATCH 10/11] Fix missing complete operation. --- src/VisualStudio/Core/Def/RoslynPackage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 06a87a1dcb87d..4e453b5131350 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -110,7 +110,7 @@ private async Task InitializeWorkspaceFailureOutputWindowAsync() { using var outputChannelStore = await serviceBrokerClient.GetProxyAsync(VisualStudioServices.VS2019_4.OutputChannelStore).ConfigureAwait(false); await outputChannelStore.Proxy.WriteLineAsync(ServicesVSResources.IntelliSense, eventArgs.Diagnostic.ToString()).ConfigureAwait(false); - }); + }).CompletesAsyncOperation(asyncToken); }; } From 6323bd57107454c314652359e18c4bd67876e2df Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 25 Sep 2019 10:29:08 -0700 Subject: [PATCH 11/11] Update docs to specify 16.4 as new required version. --- .../Building, Debugging, and Testing on Windows.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contributing/Building, Debugging, and Testing on Windows.md b/docs/contributing/Building, Debugging, and Testing on Windows.md index 57e11f416e68f..657014134430f 100644 --- a/docs/contributing/Building, Debugging, and Testing on Windows.md +++ b/docs/contributing/Building, Debugging, and Testing on Windows.md @@ -15,9 +15,9 @@ The minimal required version of .NET Framework is 4.7.2. ## Developing with Visual Studio 2019 -1. [Visual Studio 2019 16.2](https://visualstudio.microsoft.com/downloads/) +1. [Visual Studio 2019 16.4](https://visualstudio.microsoft.com/downloads/) - Ensure C#, VB, MSBuild, .NET Core and Visual Studio Extensibility are included in the selected work loads - - Ensure Visual Studio is on Version "16.2" or greater + - Ensure Visual Studio is on Version "16.4" or greater - Ensure "Use Previews" is checked in Tools -> Options -> Projects and Solutions -> .NET Core 1. [.NET Core SDK 3.0 Preview 6](https://dotnet.microsoft.com/download/dotnet-core/3.0) [Windows x64 installer](https://dotnetcli.azureedge.net/dotnet/Sdk/3.0.100-preview6-012264/dotnet-sdk-3.0.100-preview6-012264-win-x64.exe ) 1. [PowerShell 5.0 or newer](https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell). If you are on Windows 10, you are fine; you'll only need to upgrade if you're on earlier versions of Windows. The download link is under the ["Upgrading existing Windows PowerShell"](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6#upgrading-existing-windows-powershell) heading.