diff --git a/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs index 6e65f4658ae12..62457ed87a60a 100644 --- a/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs @@ -36,7 +36,6 @@ public async Task TestGetTagsOnBufferTagger() var provider = new CopyPasteAndPrintingClassificationBufferTaggerProvider( workspace.ExportProvider.GetExportedValue(), - workspace.ExportProvider.GetExportedValue(), workspace.ExportProvider.GetExportedValue(), listenerProvider); diff --git a/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs b/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs index 06215a568c9aa..170c16cc50fc6 100644 --- a/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs +++ b/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.Tagger.cs @@ -108,10 +108,12 @@ private SnapshotSpan? CachedTaggedSpan private void OnEventSourceChanged(object sender, TaggerEventArgs _) { - _owner._notificationService.RegisterNotification( - OnEventSourceChanged_OnForeground, - _owner._asyncListener.BeginAsyncOperation("SemanticClassificationBufferTaggerProvider"), - _cancellationTokenSource.Token); + _owner.ThreadingContext.JoinableTaskFactory.RunAsync(async () => + { + using var _ = _owner._asyncListener.BeginAsyncOperation("SemanticClassificationBufferTaggerProvider"); + await _owner.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_cancellationTokenSource.Token); + OnEventSourceChanged_OnForeground(); + }); } private void OnEventSourceChanged_OnForeground() diff --git a/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.cs index f2037a6b729b0..a6118f3c23c73 100644 --- a/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Classification/CopyPasteAndPrintingClassificationBufferTaggerProvider.cs @@ -29,19 +29,16 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Classification internal partial class CopyPasteAndPrintingClassificationBufferTaggerProvider : ForegroundThreadAffinitizedObject, ITaggerProvider { private readonly IAsynchronousOperationListener _asyncListener; - private readonly IForegroundNotificationService _notificationService; private readonly ClassificationTypeMap _typeMap; [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] public CopyPasteAndPrintingClassificationBufferTaggerProvider( IThreadingContext threadingContext, - IForegroundNotificationService notificationService, ClassificationTypeMap typeMap, IAsynchronousOperationListenerProvider listenerProvider) : base(threadingContext) { - _notificationService = notificationService; _typeMap = typeMap; _asyncListener = listenerProvider.GetListener(FeatureAttribute.Classification); } diff --git a/src/VisualStudio/Core/Def/Implementation/InfoBar/VisualStudioInfoBarService.cs b/src/VisualStudio/Core/Def/Implementation/InfoBar/VisualStudioInfoBarService.cs index ac21ff0268e4a..35cd555a99e19 100644 --- a/src/VisualStudio/Core/Def/Implementation/InfoBar/VisualStudioInfoBarService.cs +++ b/src/VisualStudio/Core/Def/Implementation/InfoBar/VisualStudioInfoBarService.cs @@ -24,7 +24,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation internal class VisualStudioInfoBarService : ForegroundThreadAffinitizedObject, IInfoBarService { private readonly SVsServiceProvider _serviceProvider; - private readonly IForegroundNotificationService _foregroundNotificationService; private readonly IAsynchronousOperationListener _listener; [ImportingConstructor] @@ -32,12 +31,10 @@ internal class VisualStudioInfoBarService : ForegroundThreadAffinitizedObject, I public VisualStudioInfoBarService( IThreadingContext threadingContext, SVsServiceProvider serviceProvider, - IForegroundNotificationService foregroundNotificationService, IAsynchronousOperationListenerProvider listenerProvider) : base(threadingContext) { _serviceProvider = serviceProvider; - _foregroundNotificationService = foregroundNotificationService; _listener = listenerProvider.GetListener(FeatureAttribute.InfoBar); } @@ -46,13 +43,13 @@ public void ShowInfoBar(string message, params InfoBarUI[] items) ThisCanBeCalledOnAnyThread(); // We can be called from any thread since errors can occur anywhere, however we can only construct and InfoBar from the UI thread. - _foregroundNotificationService.RegisterNotification(() => + this.ThreadingContext.JoinableTaskFactory.RunAsync(async () => { + using var _ = _listener.BeginAsyncOperation(nameof(ShowInfoBar)); + await this.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(ThreadingContext.DisposalToken); if (TryGetInfoBarData(out var infoBarHost)) - { CreateInfoBar(infoBarHost, message, items); - } - }, _listener.BeginAsyncOperation(nameof(ShowInfoBar)), ThreadingContext.DisposalToken); + }); } private bool TryGetInfoBarData(out IVsInfoBarHost infoBarHost) diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.RuleSetFile.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.RuleSetFile.cs index c33167f72bcb3..b77308868e46e 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.RuleSetFile.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.RuleSetFile.cs @@ -8,7 +8,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Shared.TestHooks; namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem { @@ -177,8 +179,12 @@ private void IncludeUpdated(object sender, string fileChanged) // waiting for the foreground thread to release its lock on the file change service. // To avoid this, just queue up a Task to do the work on the foreground thread later, after // the lock on the file change service has been released. - _ruleSetManager._foregroundNotificationService.RegisterNotification( - () => IncludeUpdateCore(), _ruleSetManager._listener.BeginAsyncOperation("IncludeUpdated"), _disposalToken); + _ruleSetManager._threadingContext.JoinableTaskFactory.RunAsync(async () => + { + using var _ = _ruleSetManager._listener.BeginAsyncOperation("IncludeUpdated"); + await _ruleSetManager._threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, _disposalToken); + IncludeUpdateCore(); + }); } private void IncludeUpdateCore() diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.cs index a0734e94a6fa2..e556902faaed3 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManager.cs @@ -4,7 +4,7 @@ #nullable disable -using Microsoft.CodeAnalysis.Editor; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.Utilities; @@ -13,17 +13,19 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem { internal sealed partial class VisualStudioRuleSetManager : IWorkspaceService { + private readonly IThreadingContext _threadingContext; private readonly FileChangeWatcher _fileChangeWatcher; - private readonly IForegroundNotificationService _foregroundNotificationService; private readonly IAsynchronousOperationListener _listener; private readonly ReferenceCountedDisposableCache _ruleSetFileMap = new(); public VisualStudioRuleSetManager( - FileChangeWatcher fileChangeWatcher, IForegroundNotificationService foregroundNotificationService, IAsynchronousOperationListener listener) + IThreadingContext threadingContext, + FileChangeWatcher fileChangeWatcher, + IAsynchronousOperationListener listener) { + _threadingContext = threadingContext; _fileChangeWatcher = fileChangeWatcher; - _foregroundNotificationService = foregroundNotificationService; _listener = listener; } diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManagerFactory.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManagerFactory.cs index f218e47ec7bc3..b12dda642a839 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManagerFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/RuleSets/VisualStudioRuleSetManagerFactory.cs @@ -2,41 +2,35 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; -using System.Collections.Generic; using System.Composition; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem { [ExportWorkspaceServiceFactory(typeof(VisualStudioRuleSetManager), ServiceLayer.Host), Shared] internal sealed class VisualStudioRuleSetManagerFactory : IWorkspaceServiceFactory { + private readonly IThreadingContext _threadingContext; private readonly FileChangeWatcherProvider _fileChangeWatcherProvider; - private readonly IForegroundNotificationService _foregroundNotificationService; private readonly IAsynchronousOperationListener _listener; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public VisualStudioRuleSetManagerFactory( + IThreadingContext threadingContext, FileChangeWatcherProvider fileChangeWatcherProvider, - IForegroundNotificationService foregroundNotificationService, IAsynchronousOperationListenerProvider listenerProvider) { + _threadingContext = threadingContext; _fileChangeWatcherProvider = fileChangeWatcherProvider; - _foregroundNotificationService = foregroundNotificationService; _listener = listenerProvider.GetListener(FeatureAttribute.RuleSetEditor); } public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) - => new VisualStudioRuleSetManager(_fileChangeWatcherProvider.Watcher, _foregroundNotificationService, _listener); + => new VisualStudioRuleSetManager(_threadingContext, _fileChangeWatcherProvider.Watcher, _listener); } } diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioRuleSetTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioRuleSetTests.vb index 80fe5af3d256d..fafb1ab5b1548 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioRuleSetTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioRuleSetTests.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Editor +Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.Test.Utilities @@ -48,7 +49,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Dim fileChangeService = New MockVsFileChangeEx Dim fileChangeWatcher = New FileChangeWatcher(Task.FromResult(Of IVsAsyncFileChangeEx)(fileChangeService)) - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), AsynchronousOperationListenerProvider.NullListener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, AsynchronousOperationListenerProvider.NullListener) Using visualStudioRuleSet = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) ' Signing up for file change notifications is lazy, so read the rule set to force it. @@ -92,7 +93,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Using workspace = New TestWorkspace() Dim fileChangeService = New MockVsFileChangeEx Dim fileChangeWatcher = New FileChangeWatcher(Task.FromResult(Of IVsAsyncFileChangeEx)(fileChangeService)) - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), AsynchronousOperationListenerProvider.NullListener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, AsynchronousOperationListenerProvider.NullListener) Using visualStudioRuleSet = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) ' Signing up for file change notifications is lazy, so read the rule set to force it. @@ -140,7 +141,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim listener = listenerProvider.GetListener("test") - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), listener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, listener) Using ruleSet1 = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) Dim handlerCalled As Boolean = False AddHandler ruleSet1.Target.Value.UpdatedOnDisk, Sub() handlerCalled = True @@ -181,7 +182,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim listener = listenerProvider.GetListener("test") - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), listener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, listener) Using ruleSet1 = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) ' Signing up for file change notifications is lazy, so read the rule set to force it. @@ -226,7 +227,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Using workspace = New TestWorkspace() Dim fileChangeService = New MockVsFileChangeEx Dim fileChangeWatcher = New FileChangeWatcher(Task.FromResult(Of IVsAsyncFileChangeEx)(fileChangeService)) - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), AsynchronousOperationListenerProvider.NullListener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, AsynchronousOperationListenerProvider.NullListener) Using ruleSet1 = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) ' Signing up for file change notifications is lazy, so read the rule set to force it. @@ -264,7 +265,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim Using workspace = New TestWorkspace() Dim fileChangeService = New MockVsFileChangeEx Dim fileChangeWatcher = New FileChangeWatcher(Task.FromResult(Of IVsAsyncFileChangeEx)(fileChangeService)) - Dim ruleSetManager = New VisualStudioRuleSetManager(fileChangeWatcher, workspace.ExportProvider.GetExportedValue(Of IForegroundNotificationService)(), AsynchronousOperationListenerProvider.NullListener) + Dim ruleSetManager = New VisualStudioRuleSetManager(workspace.ExportProvider.GetExportedValue(Of IThreadingContext), fileChangeWatcher, AsynchronousOperationListenerProvider.NullListener) Using ruleSet = ruleSetManager.GetOrCreateRuleSet(ruleSetPath) Dim generalDiagnosticOption = ruleSet.Target.Value.GetGeneralDiagnosticOption()