chore(analyzers): MS VS Threading analyzers (Tier 2 close-out)#99
Conversation
Replaces the originally-planned custom Roslyn analyzer (PR #99 thread) with Microsoft's battle-tested implementation of the same rule set. After re-evaluating, writing a custom analyzer for one rule (.Result / .Wait() on Task with type info) wasn't a good use of time when Microsoft ships analyzers covering that exact class of bug plus many related async pitfalls, and maintains them across .NET versions. Wiring: - Directory.Packages.props pins the package version centrally. - Directory.Build.props references it from every project with PrivateAssets=all so consumers don't transitively pull the analyzer. Two rules intentionally disabled in .editorconfig with justification: - VSTHRD200 (Async suffix) — clashes with MediatR / Wolverine handler discovery which binds on the literal method name `Handle`. Renaming would break dispatch. - VSTHRD111 (ConfigureAwait) — WPF/WinForms safeguard; modern ASP.NET Core has no SynchronizationContext to deadlock against. The remaining VSTHRD rules (002 sync-over-async, 100 async-void, 110 unobserved Task, ...) fire as errors and gate the build. Baseline build is clean — no existing violations to suppress or allow-list. Updates patterns.md § Async patterns to document the analyzer and the two disabled rules. agent-checklist.md CI-only gates list includes the new analyzer category. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR introduces Microsoft.VisualStudio.Threading.Analyzers to enforce async-safety patterns across the codebase. The package is centrally versioned, referenced in all projects, configured with selective rule overrides for specific false-positive cases, and documented alongside existing async guidance and CI validation criteria. ChangesAsync-Safety Analyzer Integration
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Summary
Final Tier 2 piece. Replaces the originally-planned custom Roslyn analyzer for
.Result/.Wait()onTask(PR #99 thread) with Microsoft'sMicrosoft.VisualStudio.Threading.Analyzerspackage — same rule plus a dozen related async pitfalls, maintained by Microsoft across .NET versions, no custom maintenance burden.After re-evaluating: writing a custom Roslyn analyzer (new netstandard2.0 project, Microsoft.CodeAnalysis.Testing setup, packaging quirks, ongoing maintenance) for one rule when Microsoft ships exactly that rule for free is not a good ROI tradeoff. The DiagnosticAnalyzer infrastructure also adds a ~5h initial cost we don't recover.
Baseline build is clean — no existing violations to suppress or allow-list.
What this enables
.Result/.Wait()/.GetAwaiter().GetResult()onTask(sync-over-async deadlock recipe). Type-aware — no false positives from domain types namedWait/Result.async voidmethods (unrecoverable exceptions).await).What this intentionally disables
Two rules suppressed in
.editorconfigwith justification:Handle.ConfigureAwait(bool)) — WPF/WinForms safeguard; modern ASP.NET Core has noSynchronizationContextto deadlock against.Linked spec
No feature — process improvement. References:
Requirements & rules followed
dotnet build Axis.slnclean (0 errors, 0 warnings); architecture tests322/322;dotnet formatexit 0.patterns.md§ Async patterns documents the analyzer and disabled rules;agent-checklist.mdCI-only gates list updated.TODO/FIXME/NotImplementedException/ placeholder / stub undersrc/,tests/,frontend/src/This closes Tier 2 of the architecture-fitness expansion. Cumulative coverage across PRs #94-99:
Axis.Architecture.Tests(PR #94)Axis.Architecture.Tests(PR #95)Directory.Packages.props(PR #96)Axis.Api.Tests.Architecture(PR #97)DateTime.Now, raw SQL cross-module, async deadlockscripts/check-doc-drift.sh(PR #98)Summary by CodeRabbit
Chores
Documentation