diff --git a/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs b/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs index 00c67861e94aa..4b2cecef0baca 100644 --- a/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs +++ b/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs @@ -420,26 +420,29 @@ public void Done() public bool SupportedDiagnosticId(ProjectId projectId, string id) { - if (_diagnosticIdMap.TryGetValue(projectId, out var ids)) + lock (_diagnosticIdMap) { - return ids.Contains(id); - } + if (_diagnosticIdMap.TryGetValue(projectId, out var ids)) + { + return ids.Contains(id); + } - // set ids set - var map = new HashSet(); - _diagnosticIdMap.Add(projectId, map); + // set ids set + var map = new HashSet(); + _diagnosticIdMap.Add(projectId, map); - var project = _solution.GetProject(projectId); - if (project == null) - { - // projectId no longer exist, return false; - return false; - } + var project = _solution.GetProject(projectId); + if (project == null) + { + // projectId no longer exist, return false; + return false; + } - var descriptorMap = _owner._diagnosticService.GetDiagnosticDescriptors(project); - map.UnionWith(descriptorMap.Values.SelectMany(v => v.Select(d => d.Id))); + var descriptorMap = _owner._diagnosticService.GetDiagnosticDescriptors(project); + map.UnionWith(descriptorMap.Values.SelectMany(v => v.Select(d => d.Id))); - return map.Contains(id); + return map.Contains(id); + } } public ImmutableArray GetBuildDiagnostics() diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index c1870799b2c95..6d86109077a0d 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -68,6 +68,20 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics End Using End Sub + + Public Sub TestExternalDiagnostics_SupportedDiagnosticId_Concurrent() + Using workspace = TestWorkspace.CreateCSharp(String.Empty) + Dim waiter = New Waiter() + Dim service = New TestDiagnosticAnalyzerService() + Dim source = New ExternalErrorDiagnosticUpdateSource(workspace, service, New MockDiagnosticUpdateSourceRegistrationService(), waiter) + + Dim project = workspace.CurrentSolution.Projects.First() + source.OnSolutionBuild(Me, Shell.UIContextChangedEventArgs.From(True)) + + Parallel.For(0, 100, Sub(i As Integer) source.SupportedDiagnosticId(project.Id, "CS1002")) + End Using + End Sub + Public Async Function TestExternalDiagnostics_DuplicatedError() As Task Using workspace = TestWorkspace.CreateCSharp(String.Empty)