diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace.cs b/src/Workspaces/Core/Portable/Workspace/Workspace.cs
index df886377f94f3..1d2443fe74b50 100644
--- a/src/Workspaces/Core/Portable/Workspace/Workspace.cs
+++ b/src/Workspaces/Core/Portable/Workspace/Workspace.cs
@@ -254,6 +254,7 @@ private protected (bool updated, Solution newSolution) SetCurrentSolution(
return UnifyLinkedDocumentContents(oldSolution, newSolution);
},
+ mayRaiseEvents: true,
onBeforeUpdate: static (oldSolution, newSolution, data) =>
{
data.onBeforeUpdate?.Invoke(oldSolution, newSolution);
@@ -342,6 +343,10 @@ static Solution UpdateExistingDocumentsToChangedDocumentContents(Solution soluti
/// Solution transformation. This may be run multiple times. As such it should be
/// a purely functional transformation on the solution instance passed to it. It should not make stateful
/// changes elsewhere.
+ /// if this operation may raise observable events;
+ /// otherwise, . If , the operation will call
+ /// to ensure listeners are registered prior to callbacks that may raise
+ /// events.
/// Action to perform immediately prior to updating .
/// The action will be passed the old that will be replaced and the exact solution
/// it will be replaced with. The latter may be different than the solution returned by (
TData data,
Func transformation,
+ bool mayRaiseEvents = true,
Action? onBeforeUpdate = null,
Action? onAfterUpdate = null)
{
@@ -363,6 +369,7 @@ private protected (Solution oldSolution, Solution newSolution) SetCurrentSolutio
useAsync: false,
data,
transformation,
+ mayRaiseEvents,
onBeforeUpdate,
onAfterUpdate,
CancellationToken.None);
@@ -371,11 +378,12 @@ private protected (Solution oldSolution, Solution newSolution) SetCurrentSolutio
#pragma warning restore CA2012 // Use ValueTasks correctly
}
- ///
+ ///
private protected async ValueTask<(Solution oldSolution, Solution newSolution)> SetCurrentSolutionAsync(
bool useAsync,
TData data,
Func transformation,
+ bool mayRaiseEvents,
Action? onBeforeUpdate,
Action? onAfterUpdate,
CancellationToken cancellationToken)
@@ -384,9 +392,12 @@ private protected (Solution oldSolution, Solution newSolution) SetCurrentSolutio
var oldSolution = Volatile.Read(ref _latestSolution);
- // Ensure our event handlers are realized prior to taking this lock. We don't want to deadlock trying
- // to obtain them when calling one of our callbacks. See https://github.com/dotnet/roslyn/issues/64681
- EnsureEventListeners();
+ if (mayRaiseEvents)
+ {
+ // Ensure our event handlers are realized prior to taking this lock. We don't want to deadlock trying
+ // to obtain them when calling one of our callbacks. See https://github.com/dotnet/roslyn/issues/64681
+ EnsureEventListeners();
+ }
while (true)
{
@@ -499,6 +510,7 @@ private void ClearSolution(bool reportChangeEvent)
this.SetCurrentSolution(
data: /*unused*/ 0,
(oldSolution, _) => this.CreateSolution(oldSolution.Id),
+ mayRaiseEvents: reportChangeEvent,
onBeforeUpdate: (_, _, _) => this.ClearSolutionData(),
onAfterUpdate: (oldSolution, newSolution, _) =>
{