You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello, I am on the Visual Studio performance team and our telemetry has shown that there are high amounts of CPU being consumed by the two callstacks I pasted below. It appears that there are multiple threads accessing a HashSet at the same time, causing the HashSet to enter a corrupted state. This causes multiple threads to be stuck in an infinite loop within the HashSet. HashSet is not inherently thread-safe, so having concurrent writers into a HashSet or overlapping reader + a writer can cause issues such as infinite loops, exceptions, and incorrect values. In the case with the callstacks I pasted below, 4 threads were stuck within HashSet.Contains and 1 thread within HashSet.AddIfNotPresent, causing 5 full cores of CPU to be continuously used.
Solution
I would recommend making sure that reads and writes to the HashSet within StaticClassDependencyAnalyze are thread-safe. You can do this either by using a lock for the HashSet, or using a thread-safe collection such as a ConcurrentDictionary or ConcurrentBag.
Description
Hello, I am on the Visual Studio performance team and our telemetry has shown that there are high amounts of CPU being consumed by the two callstacks I pasted below. It appears that there are multiple threads accessing a HashSet at the same time, causing the HashSet to enter a corrupted state. This causes multiple threads to be stuck in an infinite loop within the HashSet. HashSet is not inherently thread-safe, so having concurrent writers into a HashSet or overlapping reader + a writer can cause issues such as infinite loops, exceptions, and incorrect values. In the case with the callstacks I pasted below, 4 threads were stuck within HashSet.Contains and 1 thread within HashSet.AddIfNotPresent, causing 5 full cores of CPU to be continuously used.
Solution
I would recommend making sure that reads and writes to the HashSet within StaticClassDependencyAnalyze are thread-safe. You can do this either by using a lock for the HashSet, or using a thread-safe collection such as a ConcurrentDictionary or ConcurrentBag.
CallStack 1
++microsoft.codeanalysis.ni!Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[System.ValueTuple`2[System.__Canon,Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext]](Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Action`1>, System.ValueTuple`2, System.Nullable`1)
++ microsoft.codeanalysis.csharp.ni!Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor+<>c__55`1[Microsoft.CodeAnalysis.CSharp.SyntaxKind].b__55_0(System.ValueTuple`2,Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext>)
++++share.analyzer!ET.Analyzer.StaticClassCircularDependencyAnalyzer+<>c__DisplayClass7_0.b__0(value class Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext)
++++ share.analyzer!StaticClassCircularDependencyAnalyzer.StaticClassDependencyAnalyze
++++++system.core.ni!System.Collections.Generic.HashSet`1[System.__Canon].Contains(System.__Canon)
CallStack 2
++microsoft.codeanalysis.ni!Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[System.ValueTuple`2[System.__Canon,Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext]](Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Action`1>, System.ValueTuple`2, System.Nullable`1)
++ microsoft.codeanalysis.csharp.ni!Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor+<>c__55`1[Microsoft.CodeAnalysis.CSharp.SyntaxKind].b__55_0(System.ValueTuple`2,Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext>)
++++share.analyzer!ET.Analyzer.StaticClassCircularDependencyAnalyzer+<>c__DisplayClass7_0.b__0(value class Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext)
++++ share.analyzer!StaticClassCircularDependencyAnalyzer.StaticClassDependencyAnalyze
++++++system.core.ni!System.Collections.Generic.HashSet`1[System.__Canon].AddIfNotPresent(System.__Canon)
The text was updated successfully, but these errors were encountered: