Add ExcludeFromCancellationTokenAnalysisAttribute to opt out of the CancellationToken rules - #1364
Merged
meziantou merged 2 commits intoAug 30, 2026
Conversation
`AssertNoAnalyzerException` takes the `ConcurrentBag` collected during the analysis as an `IReadOnlyCollection<T>`, which CA1859 reports as an error, and `ConcurrentBag.Count` walks the whole bag, which CA1836 reports once the parameter is typed as the concrete type. The test projects did not compile before this commit.
…Attribute Some methods are fine to call without a `CancellationToken`, even when they have an overload that takes one and a token is available in the scope: cleanup and shutdown paths, telemetry flushes, fire-and-forget writes. Until now the only ways to silence the diagnostic were `#pragma warning disable` at every call site, or lowering the severity for a whole file or folder. The new `ExcludeFromCancellationTokenAnalysisAttribute` of the `Meziantou.Analyzer.Annotations` package marks a called method as valid to call without a token. No MA0032/MA0040/MA0079/MA0080 diagnostic is reported for the calls to an excluded method. The methods of the current project can be annotated directly, and the methods of another assembly at the assembly level, using their XML documentation id or their containing type and name, optionally with the parameter types to restrict the exclusion to a single overload. This mirrors `ExcludeFromBlockingCallAnalysisAttribute`, whose assembly attribute resolution is extracted to the new `AnnotationExclusions` helper and shared by both analyzers. A method matches by its symbol, its original definition, and its unreduced form, so generic methods and extension methods called with the instance syntax are excluded too. The lookup runs only once the analyzer is about to report a diagnostic, and its result is cached per compilation.
meziantou
enabled auto-merge (squash)
August 30, 2026 19:43
meziantou
deleted the
feature/ma0040-cancellation-token-suppress-58f1b8
branch
August 30, 2026 19:43
This was referenced Aug 30, 2026
Open
Open
Open
This was referenced Aug 31, 2026
Open
Open
Open
Open
Open
Open
Open
meziantou
added a commit
that referenced
this pull request
Aug 31, 2026
main added ExcludeFromCancellationTokenAnalysisAttribute (#1364) while this branch replaced ProjectBuilder with the Roslyn SDK testing harness. - Keep the deletion of ProjectBuilder.Validation.cs: main only adjusted the analyzer exception assert of a file this branch removes with the old harness. - Convert the eight ExcludedMethod tests main added to the new harness, so the new attribute keeps its coverage.
This was referenced Aug 31, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
MA0040 (and its siblings MA0032/MA0079/MA0080) reports every call to a method that has a
CancellationTokenoverload. Some methods are legitimately called without a token — cleanup and shutdown paths, telemetry flushes, fire-and-forget writes. Until now the only escapes were#pragma warning disableat every call site, or lowering the severity for a whole file or folder. Neither expresses "this API is fine to call without a token" once, project-wide.What
A new
ExcludeFromCancellationTokenAnalysisAttributein theMeziantou.Analyzer.Annotationspackage marks a called method as excluded. No MA0032/MA0040/MA0079/MA0080 diagnostic is reported for the calls to it.The methods of the current project can be annotated directly:
The methods of another assembly are annotated at the assembly level, using their XML documentation id or their containing type and name. The parameter types are optional and restrict the exclusion to a single overload:
This mirrors the existing
ExcludeFromBlockingCallAnalysisAttribute. Its assembly-attribute resolution is extracted fromDoNotUseBlockingCallInAsyncContextAnalyzerinto a newAnnotationExclusionshelper, now shared by both analyzers.Notes for the reviewer
OriginalDefinitionand itsReducedFrom, so generic methods and extension methods called with the instance syntax are excluded too.[Conditional("MEZIANTOU_ANALYZER_ANNOTATIONS")]: the declaration-site form only crosses assembly boundaries when the declaring project defines that symbol. The assembly-level form is the documented answer for third-party APIs.Meziantou.Analyzer.Annotationsis bumped to 1.8.0, and its README plus the four rule docs are updated.tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.Validation.csdid not compile (CA1859, then CA1836 onAssertNoAnalyzerException). It is fixed separately so it can be cherry-picked or dropped.Verification
UseAnOverloadThatHasCancellationTokenAnalyzerTestscovering both attribute forms, the parameter-types overload filter, MA0032 with no token in scope,await foreach, generic and extension methods, and negative controls.dotnet run --project src/DocumentationGeneratorexits 0.