Repository navigation
Upgrade Particular Analyzers and triage new diagnostics - #5724
Conversation
d2a896e to
0a09435
Compare
| using (StartExecuting()) | ||
| { | ||
| OnExecuting(); | ||
| await ExecuteAsync(obj); |
There was a problem hiding this comment.
Would it be better to just discard the result to avoid the pragma?
There's no code to resume the end result (abandoned task) is the same
| _ = ExecuteAsync(obj); |
There was a problem hiding this comment.
Not quite equivalent, unfortunately. The await is inside using (StartExecuting()), and that disposable is what flips isExecuting back to false and re-raises CanExecuteChanged. If we discard the task, the using block exits synchronously and the command re-enables itself while the work is still running, so we lose the double-click guard. There's also an exception-handling difference: with async void an unhandled exception is rethrown on the WPF dispatcher, whereas a discarded task becomes a silently unobserved task exception.
| NotifyOfPropertyChange(nameof(Instances)); | ||
| } | ||
|
|
||
| // TODO: this is a genuine async void, not an event handler. Because it returns at the first |
There was a problem hiding this comment.
Similar to my other comment, could you make this async Task and discard the task at the caller?
There was a problem hiding this comment.
Agreed it should be async Task, but discarding at the call sites would keep the bug the TODO describes. HandleAsync(RefreshInstances) needs to genuinely await it, otherwise PostRefreshInstances is published before the removals have finished, which is the exact ordering that method's own remarks say must not happen.
The blocker is the other call site in the constructor. The clean fix is to move that call into RxScreen.OnInitialize(), which is awaited properly, and then await at both sites. That's a real behaviour change, so I'd rather not fold it into an analyzer-upgrade PR. I will do a standalone PR to fix it.
| using NServiceBus.CustomChecks; | ||
| using NServiceBus.Transport.IBMMQ; | ||
|
|
||
| #pragma warning disable PS0024 // The I is from IBM, matching NServiceBus.Transport.IBMMQ |
There was a problem hiding this comment.
Is there a way you can define permitted Acronyms instead of using the pragma?
There was a problem hiding this comment.
I looked into it and there's no such option.
Unpins the Particular.Analyzers version, enabling newer rules across the solution. New warnings introduced by the upgrade are suppressed in `.editorconfig` files as technical debt, with a plan to address them incrementally. Includes initial fixes for `DateTime` to `DateTimeOffset` usage, and adds pragmas for intentional `async void` and reference equality usages identified by the analyzers.
0a09435 to
d4523ed
Compare
Why
Custom.Build.propshas pinnedParticularAnalyzersVersionto 0.9.0 since 2021, with the comment"Remove after upgrading to NServiceBus 8.x." We're on NServiceBus 10.2.8. Version 0.9.0 predates
Particular.Analyzers' cancellation-token rules entirely, so the analyzer has been silently unable
to catch missing/unpropagated
CancellationTokenparameters for years. This is the first step inthreading cancellation through the platform: turn the guardrail back on before touching any call sites.
What this does
ParticularAnalyzersVersionnow resolves 2.1.4 fromDirectory.Build.props.Error-severity by default and would otherwise break everybuild immediately:
PS0023(DateTime.Nowvs.UtcNow) inActiveLicense.cs— also a latent bug, since the trial-windowtests already assume UTC.
PS0025/PS0027inServiceControl.Config(WPF):async voidand reference-equality collectionwarnings. Five are legitimate WPF idioms (
ICommand.Execute,Application.Startup, view/thread caches)and are suppressed at the site with justification. The sixth,
ListInstancesViewModel.AddAndRemoveInstances,is a genuine bug — it returns at its first
await, soRefreshInstancespublishes before removals finish —and is suppressed with a
TODOinstead, since fixing it needs the constructor call site restructured.in
ScatterGatherApi, fourDateTime→DateTimeOffsetcasts that are provably UTC, and a rename(
IHostApplicationBuilderExtensions→HostApplicationBuilderExtensions, unreferenced by name)..editorconfigdebt block to every project still carrying cancellation-rule warnings (62 projects),listing only the rules that project actually violates, so each block doubles as that project's remaining
work. This is a ratchet: a rule can only be deleted from a block once the project has zero violations of it.
What this doesn't do
No
CancellationTokenpropagation yet. That starts in the next PR. This is purely: turn the analyzer back on,fix what's
Error-severity, and record everything else as tracked debt instead of leaving it invisible.