Skip to content
代码片段 群组 项目
未验证 提交 45ab8454 编辑于 作者: Jinu's avatar Jinu 提交者: GitHub
浏览文件

Merge pull request #36973 from jasonmalinowski/tactical-fix-for-experimentation-service-deadlock

Workaround IExperimentationService having a UI thread dependency
No related branches found
No related tags found
无相关合并请求
......@@ -41,6 +41,9 @@ public VisualStudioProject CreateAndAddToWorkspace(string projectSystemName, str
// HACK: Fetch this service to ensure it's still created on the UI thread; once this is moved off we'll need to fix up it's constructor to be free-threaded.
_visualStudioWorkspaceImpl.Services.GetRequiredService<VisualStudioMetadataReferenceManager>();
// HACK: since we're on the UI thread, ensure we initialize our options provider which depends on a UI-affinitized experimentation service
_visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitialized();
var id = ProjectId.CreateNewId(projectSystemName);
var directoryNameOpt = creationInfo.FilePath != null ? Path.GetDirectoryName(creationInfo.FilePath) : null;
......
......@@ -15,6 +15,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
......@@ -91,11 +92,12 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
internal FileWatchedPortableExecutableReferenceFactory FileWatchedReferenceFactory { get; }
private readonly Lazy<IProjectCodeModelFactory> _projectCodeModelFactory;
private readonly IEnumerable<IDocumentOptionsProviderFactory> _documentOptionsProviderFactories;
private bool _documentOptionsProvidersInitialized = false;
private readonly Dictionary<ProjectId, CompilationOutputs> _projectCompilationOutputs = new Dictionary<ProjectId, CompilationOutputs>();
private readonly object _projectCompilationOutputsGuard = new object();
public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider)
public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider, IEnumerable<CodeAnalysis.Options.IDocumentOptionsProviderFactory> documentOptionsProviderFactories)
: base(VisualStudioMefHostServices.Create(exportProvider))
{
_threadingContext = exportProvider.GetExportedValue<IThreadingContext>();
......@@ -103,6 +105,7 @@ public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServicePro
_textBufferFactoryService = exportProvider.GetExportedValue<ITextBufferFactoryService>();
_projectionBufferFactoryService = exportProvider.GetExportedValue<IProjectionBufferFactoryService>();
_projectCodeModelFactory = exportProvider.GetExport<IProjectCodeModelFactory>();
_documentOptionsProviderFactories = documentOptionsProviderFactories;
// We fetch this lazily because VisualStudioProjectFactory depends on VisualStudioWorkspaceImpl -- we have a circularity. Since this
// exists right now as a compat shim, we'll just do this.
......@@ -1885,5 +1888,27 @@ internal CompilationOutputs GetCompilationOutputs(ProjectId projectId)
return _projectCompilationOutputs.TryGetValue(projectId, out var outputs) ? outputs : CompilationOutputFiles.None;
}
}
internal void EnsureDocumentOptionProvidersInitialized()
{
_foregroundObject.AssertIsForeground();
if (_documentOptionsProvidersInitialized)
{
return;
}
_documentOptionsProvidersInitialized = true;
foreach (var providerFactory in _documentOptionsProviderFactories)
{
var optionsProvider = providerFactory.TryCreate(this);
if (optionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
}
}
}
......@@ -36,19 +36,9 @@ public RoslynVisualStudioWorkspace(
[ImportMany] IEnumerable<Lazy<IStreamingFindUsagesPresenter>> streamingPresenters,
[ImportMany] IEnumerable<IDocumentOptionsProviderFactory> documentOptionsProviderFactories,
[Import(typeof(SVsServiceProvider))] IAsyncServiceProvider asyncServiceProvider)
: base(exportProvider, asyncServiceProvider)
: base(exportProvider, asyncServiceProvider, documentOptionsProviderFactories)
{
_streamingPresenters = streamingPresenters;
foreach (var providerFactory in documentOptionsProviderFactories)
{
var optionsProvider = providerFactory.TryCreate(this);
if (optionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
}
internal override IInvisibleEditor OpenInvisibleEditor(DocumentId documentId)
......
......@@ -23,6 +23,7 @@ Imports Microsoft.VisualStudio.Shell.Interop
Imports Moq
Imports Microsoft.VisualStudio.LanguageServices.Implementation.TaskList
Imports Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel
Imports Microsoft.CodeAnalysis.Options
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework
......@@ -78,7 +79,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Fr
<ImportingConstructor>
Public Sub New(exportProvider As Composition.ExportProvider)
MyBase.New(exportProvider, exportProvider.GetExportedValue(Of MockServiceProvider))
MyBase.New(exportProvider,
exportProvider.GetExportedValue(Of MockServiceProvider),
exportProvider.GetExportedValues(Of IDocumentOptionsProviderFactory))
End Sub
Public Overrides Sub DisplayReferencedSymbols(solution As Microsoft.CodeAnalysis.Solution, referencedSymbols As IEnumerable(Of ReferencedSymbol))
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册