Skip to content

Commit

Permalink
Merge pull request #74656 from davidwengier/DontRootSolutionsExclamat…
Browse files Browse the repository at this point in the history
…ionMark

Unsubscribe from UIContext events when the LSP server exits
  • Loading branch information
davidwengier committed Aug 6, 2024
2 parents 1d424c1 + 7c0fea9 commit 969c517
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ internal interface IUIContextActivationService
/// <summary>
/// Executes the specified action when the UIContext first becomes active, or immediately if it is already active
/// </summary>
void ExecuteWhenActivated(Guid uiContext, Action action);
IDisposable ExecuteWhenActivated(Guid uiContext, Action action);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ private class RazorDynamicRegistrationService(
IClientLanguageServerManager? clientLanguageServerManager) : ILspService, IOnInitialized, IDisposable
{
private readonly CancellationTokenSource _disposalTokenSource = new();
private IDisposable? _activation;

public void Dispose()
{
_activation?.Dispose();
_activation = null;
_disposalTokenSource.Cancel();
}

Expand All @@ -56,7 +59,7 @@ public Task OnInitializedAsync(ClientCapabilities clientCapabilities, RequestCon
}
else
{
uIContextActivationService.ExecuteWhenActivated(Constants.RazorCohostingUIContext, InitializeRazor);
_activation = uIContextActivationService.ExecuteWhenActivated(Constants.RazorCohostingUIContext, InitializeRazor);
}

return Task.CompletedTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.VisualStudio.Shell;
using Roslyn.Utilities;

namespace Microsoft.VisualStudio.LanguageServices.Implementation;

Expand All @@ -15,9 +16,60 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation;
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class VisualStudioUIContextActivationService() : IUIContextActivationService
{
public void ExecuteWhenActivated(Guid uiContext, Action action)
public IDisposable ExecuteWhenActivated(Guid uiContext, Action action)
{
var context = UIContext.FromUIContextGuid(uiContext);
context.WhenActivated(action);
if (context.IsActive)
{
action();
return EmptyDisposable.Instance;
}
else
{
return new WhenActivatedHandler(context, action);
}
}

private sealed class EmptyDisposable : IDisposable
{
public static EmptyDisposable Instance = new();

public void Dispose()
{
}
}

private sealed class WhenActivatedHandler : IDisposable
{
private readonly Action _action;
private UIContext? _context;

public WhenActivatedHandler(UIContext context, Action action)
{
_context = context;
_action = action;
_context.UIContextChanged += OnContextChanged;
}

public void Dispose()
{
if (_context is not null)
{
_context.UIContextChanged -= OnContextChanged;
}

_context = null;
}

private void OnContextChanged(object sender, UIContextChangedEventArgs e)
{
Contract.ThrowIfNull(_context);

if (e.Activated)
{
_action();
Dispose();
}
}
}
}

0 comments on commit 969c517

Please sign in to comment.