From fc628b5c300e4a7df087db6728f62b32ab29a655 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 4 Dec 2017 06:36:49 -0600 Subject: [PATCH] Avoid a capturing local variables on the GetOptionsAsync fast path --- .../Portable/Workspace/Solution/Document.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs index 874f8d8956e..4b470b8f4a3 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs @@ -467,6 +467,7 @@ public Task GetOptionsAsync(CancellationToken cancellationTok return GetOptionsAsync(Project.Solution.Options, cancellationToken); } + [PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", AllowCaptures = false)] internal Task GetOptionsAsync(OptionSet solutionOptions, CancellationToken cancellationToken) { // TODO: we have this workaround since Solution.Options is not actually snapshot but just return Workspace.Options which violate snapshot model. @@ -475,17 +476,22 @@ internal Task GetOptionsAsync(OptionSet solutionOptions, Canc // snapshot model. once that is fixed, we can remove this workaround - https://github.com/dotnet/roslyn/issues/19284 if (_cachedOptions == null) { - var newAsyncLazy = new AsyncLazy(async c => - { - var optionsService = Project.Solution.Workspace.Services.GetRequiredService(); - var documentOptionSet = await optionsService.GetUpdatedOptionSetForDocumentAsync(this, solutionOptions, c).ConfigureAwait(false); - return new DocumentOptionSet(documentOptionSet, Project.Language); - }, cacheResult: true); - - Interlocked.CompareExchange(ref _cachedOptions, newAsyncLazy, comparand: null); + InitializeCachedOptions(solutionOptions, cancellationToken); } return _cachedOptions.GetValueAsync(cancellationToken); } + + private void InitializeCachedOptions(OptionSet solutionOptions, CancellationToken cancellationToken) + { + var newAsyncLazy = new AsyncLazy(async c => + { + var optionsService = Project.Solution.Workspace.Services.GetRequiredService(); + var documentOptionSet = await optionsService.GetUpdatedOptionSetForDocumentAsync(this, solutionOptions, c).ConfigureAwait(false); + return new DocumentOptionSet(documentOptionSet, Project.Language); + }, cacheResult: true); + + Interlocked.CompareExchange(ref _cachedOptions, newAsyncLazy, comparand: null); + } } } -- GitLab