-
Notifications
You must be signed in to change notification settings - Fork 466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent SemaphoreSlim.Wait(0) from triggering CA1849 #7310
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7310 +/- ##
========================================
Coverage 96.47% 96.48%
========================================
Files 1443 1443
Lines 345400 345525 +125
Branches 11364 11369 +5
========================================
+ Hits 333239 333368 +129
+ Misses 9282 9275 -7
- Partials 2879 2882 +3 |
async Task M() | ||
{ | ||
SemaphoreSlim s = new SemaphoreSlim(0); | ||
s.Wait(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 I feel like all four of the "zero" cases could be in one [Theory]
, but broken out is fine.
IFieldSymbol? timeSpanZero = timeSpanType?.GetMembers(nameof(TimeSpan.Zero)) | ||
.OfType<IFieldSymbol>() | ||
.FirstOrDefault(); | ||
ISet<IMethodSymbol> semaphoreSlimWaitMethods = semaphoreSlimType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImmutableArray<T>
will be at least as fast asISet
for such a small collection- Not all overloads are included here, so I suggested a clarifying name
ISet<IMethodSymbol> semaphoreSlimWaitMethods = semaphoreSlimType | |
ImmutableArray<IMethodSymbol> semaphoreSlimWaitWithTimeoutMethods = semaphoreSlimType |
@@ -148,6 +165,21 @@ public override void Initialize(AnalysisContext context) | |||
}); | |||
} | |||
|
|||
private static bool IsSemaphoreSlimWaitWithZeroArgumentInvocation(IInvocationOperation invocation, IFieldSymbol? timeSpanZero, ISet<IMethodSymbol> semaphoreSlimWaitMethods) | |||
{ | |||
if (!semaphoreSlimWaitMethods.Contains(invocation.TargetMethod, SymbolEqualityComparer.Default) || invocation.Arguments.IsEmpty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The arguments length check here is redundant, right? I would expect IOperation invocation to always have the same number of arguments as parameters, and we already know from the set creation above that only overloads with one or more parameters is contained in the collection.
if (!semaphoreSlimWaitMethods.Contains(invocation.TargetMethod, SymbolEqualityComparer.Default) || invocation.Arguments.IsEmpty) | |
if (!semaphoreSlimWaitMethods.Contains(invocation.TargetMethod, SymbolEqualityComparer.Default)) |
If you remove the check, feel free to include a Debug.Assert
line to make it clear for future readers users why it was excluded.
@sharwell Thanks for reviewing this! |
@sharwell Can this be merged? |
Affected analyzer: UseAsyncMethodInAsyncContext
Affected diagnostic IDs: CA1849
This PR suppresses CA1849 for calls to
SemaphoreSlim.Wait(0)
,SemaphoreSlim.Wait(0, CancellationToken)
,SemaphoreSlim.Wait(TimeSpan.Zero)
andSemaphoreSlim.Wait(TimeSpan.Zero, CancellationToken)
.Fixes #7271