diff --git a/src/Custom.Build.props b/src/Custom.Build.props
index 4e8b08ce0d..dd2a87b3cf 100644
--- a/src/Custom.Build.props
+++ b/src/Custom.Build.props
@@ -8,8 +8,6 @@
falseParticular.ServiceControl.Management$(ArtifactsPath)PowerShellModules\$(PowerShellModuleName)\
-
- 0.9.0true
diff --git a/src/Particular.LicensingComponent.Persistence.InMemory/.editorconfig b/src/Particular.LicensingComponent.Persistence.InMemory/.editorconfig
index 320c6fad7c..8a988261dd 100644
--- a/src/Particular.LicensingComponent.Persistence.InMemory/.editorconfig
+++ b/src/Particular.LicensingComponent.Persistence.InMemory/.editorconfig
@@ -8,4 +8,9 @@ dotnet_diagnostic.CA2007.severity = none
# Justification: Rider displays an error to do with "Accessibility modifiers required (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0040)"
dotnet_diagnostic.IDE0040.severity = none
-csharp_style_var_elsewhere = true:error
\ No newline at end of file
+csharp_style_var_elsewhere = true:error
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
diff --git a/src/Particular.LicensingComponent.Persistence/.editorconfig b/src/Particular.LicensingComponent.Persistence/.editorconfig
index ff993b49bb..eae5d84087 100644
--- a/src/Particular.LicensingComponent.Persistence/.editorconfig
+++ b/src/Particular.LicensingComponent.Persistence/.editorconfig
@@ -2,3 +2,8 @@
# Justification: ServiceControl app has no synchronization context
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
diff --git a/src/Particular.LicensingComponent.UnitTests/.editorconfig b/src/Particular.LicensingComponent.UnitTests/.editorconfig
index 5f68a610b3..474aec5159 100644
--- a/src/Particular.LicensingComponent.UnitTests/.editorconfig
+++ b/src/Particular.LicensingComponent.UnitTests/.editorconfig
@@ -2,3 +2,11 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0006.severity = none
+dotnet_diagnostic.PS0017.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/Particular.LicensingComponent/.editorconfig b/src/Particular.LicensingComponent/.editorconfig
index f16f0e5105..97adb8c6b7 100644
--- a/src/Particular.LicensingComponent/.editorconfig
+++ b/src/Particular.LicensingComponent/.editorconfig
@@ -11,4 +11,12 @@ dotnet_diagnostic.IDE0040.severity = none
dotnet_diagnostic.IDE0010.severity = suggestion
csharp_style_var_elsewhere = true:error
-csharp_style_var_for_built_in_types = true:error
\ No newline at end of file
+csharp_style_var_for_built_in_types = true:error
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0008.severity = none
+dotnet_diagnostic.PS0017.severity = none
+dotnet_diagnostic.PS0019.severity = none
diff --git a/src/ServiceControl.AcceptanceTesting/.editorconfig b/src/ServiceControl.AcceptanceTesting/.editorconfig
index 196d6e44a8..f3c943025f 100644
--- a/src/ServiceControl.AcceptanceTesting/.editorconfig
+++ b/src/ServiceControl.AcceptanceTesting/.editorconfig
@@ -2,3 +2,10 @@
# Justification: Usage is from test projects
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0013.severity = none
+dotnet_diagnostic.PS0018.severity = none
+dotnet_diagnostic.PS0019.severity = none
diff --git a/src/ServiceControl.AcceptanceTests.RavenDB/.editorconfig b/src/ServiceControl.AcceptanceTests.RavenDB/.editorconfig
index 0279bdc2db..bbcb303765 100644
--- a/src/ServiceControl.AcceptanceTests.RavenDB/.editorconfig
+++ b/src/ServiceControl.AcceptanceTests.RavenDB/.editorconfig
@@ -1,4 +1,10 @@
[*.cs]
# Justification: Test project
-dotnet_diagnostic.CA2007.severity = none
\ No newline at end of file
+dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.AcceptanceTests/.editorconfig b/src/ServiceControl.AcceptanceTests/.editorconfig
index 5f68a610b3..4fcb63e0be 100644
--- a/src/ServiceControl.AcceptanceTests/.editorconfig
+++ b/src/ServiceControl.AcceptanceTests/.editorconfig
@@ -2,3 +2,15 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0013.severity = none
+dotnet_diagnostic.PS0017.severity = none
+dotnet_diagnostic.PS0018.severity = none
+
+# Timezone debt: these DateTime values are Kind=Unspecified or Local, so the implicit cast to
+# DateTimeOffset uses the build agent's offset. Each needs individual review before removing.
+dotnet_diagnostic.PS0022.severity = none
diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_messages_fails_multiple_times.cs b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_messages_fails_multiple_times.cs
index ffd9515517..434f6c776d 100644
--- a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_messages_fails_multiple_times.cs
+++ b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_messages_fails_multiple_times.cs
@@ -59,7 +59,7 @@ protected override TransportOperations CreateMessage(TestContext context)
{
var endpointName = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AnEndpoint));
var messageId = Guid.NewGuid().ToString();
- var earliestTimeOfFailure = DateTime.UtcNow;
+ var earliestTimeOfFailure = DateTimeOffset.UtcNow;
context.UniqueMessageId = DeterministicGuid.MakeId(messageId, endpointName).ToString();
diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_is_retried.cs b/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_is_retried.cs
index 12060bad9c..6e8859f666 100644
--- a/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_is_retried.cs
+++ b/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_is_retried.cs
@@ -131,7 +131,7 @@ protected override TransportOperations CreateMessage(TestContext context)
headers["NServiceBus.FailedQ"] = Conventions.EndpointNamingConvention(typeof(VerifyHeader));
headers["$.diagnostics.hostid"] = Guid.NewGuid().ToString();
- headers["NServiceBus.TimeOfFailure"] = DateTimeOffsetHelper.ToWireFormattedString(DateTime.UtcNow);
+ headers["NServiceBus.TimeOfFailure"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow);
var outgoingMessage = new OutgoingMessage(messageId, headers, context.BodyToSend);
diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs b/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs
index 1e90dac10b..ea6bf5a65a 100644
--- a/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs
+++ b/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs
@@ -82,7 +82,7 @@ protected override TransportOperations CreateMessage(MyContext context)
[Headers.MessageId] = i == 2 ? context.MessageId : Guid.NewGuid().ToString(),
["NServiceBus.FailedQ"] = Conventions.EndpointNamingConvention(typeof(Sendonly)),
["$.diagnostics.hostid"] = Guid.NewGuid().ToString(),
- ["NServiceBus.TimeOfFailure"] = DateTimeOffsetHelper.ToWireFormattedString(DateTime.UtcNow)
+ ["NServiceBus.TimeOfFailure"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow)
};
diff --git a/src/ServiceControl.Api/.editorconfig b/src/ServiceControl.Api/.editorconfig
new file mode 100644
index 0000000000..1942f21999
--- /dev/null
+++ b/src/ServiceControl.Api/.editorconfig
@@ -0,0 +1,7 @@
+[*.cs]
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0017.severity = none
diff --git a/src/ServiceControl.Audit.AcceptanceTests.RavenDB/.editorconfig b/src/ServiceControl.Audit.AcceptanceTests.RavenDB/.editorconfig
index 5f68a610b3..bbcb303765 100644
--- a/src/ServiceControl.Audit.AcceptanceTests.RavenDB/.editorconfig
+++ b/src/ServiceControl.Audit.AcceptanceTests.RavenDB/.editorconfig
@@ -2,3 +2,9 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.Audit.AcceptanceTests/.editorconfig b/src/ServiceControl.Audit.AcceptanceTests/.editorconfig
index 5f68a610b3..0a6ae3dffe 100644
--- a/src/ServiceControl.Audit.AcceptanceTests/.editorconfig
+++ b/src/ServiceControl.Audit.AcceptanceTests/.editorconfig
@@ -2,3 +2,8 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.Audit.Persistence.InMemory/.editorconfig b/src/ServiceControl.Audit.Persistence.InMemory/.editorconfig
index ff993b49bb..522a310bff 100644
--- a/src/ServiceControl.Audit.Persistence.InMemory/.editorconfig
+++ b/src/ServiceControl.Audit.Persistence.InMemory/.editorconfig
@@ -2,3 +2,9 @@
# Justification: ServiceControl app has no synchronization context
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/.editorconfig b/src/ServiceControl.Audit.Persistence.RavenDB/.editorconfig
index ff993b49bb..e2d491d8f7 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/.editorconfig
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/.editorconfig
@@ -2,3 +2,10 @@
# Justification: ServiceControl app has no synchronization context
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0018.severity = none
+dotnet_diagnostic.PS0020.severity = none
diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/.editorconfig b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/.editorconfig
index 5f68a610b3..d786f604c0 100644
--- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/.editorconfig
+++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/.editorconfig
@@ -2,3 +2,9 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0018.severity = none
+dotnet_diagnostic.PS0020.severity = none
diff --git a/src/ServiceControl.Audit.Persistence.Tests/.editorconfig b/src/ServiceControl.Audit.Persistence.Tests/.editorconfig
index 613ad2b9a4..d9eedc8bed 100644
--- a/src/ServiceControl.Audit.Persistence.Tests/.editorconfig
+++ b/src/ServiceControl.Audit.Persistence.Tests/.editorconfig
@@ -6,4 +6,8 @@ dotnet_diagnostic.PS0004.severity = none # A parameter of type CancellationToke
dotnet_diagnostic.PS0018.severity = none # Add a CancellationToken parameter
# Justification: Tests don't support cancellation and don't need to forward IMessageHandlerContext.CancellationToken
-dotnet_diagnostic.NSB0002.severity = suggestion
\ No newline at end of file
+dotnet_diagnostic.NSB0002.severity = suggestion
+
+# Timezone debt: these DateTime values are Kind=Unspecified or Local, so the implicit cast to
+# DateTimeOffset uses the build agent's offset. Each needs individual review before removing.
+dotnet_diagnostic.PS0022.severity = none
diff --git a/src/ServiceControl.Audit.Persistence/.editorconfig b/src/ServiceControl.Audit.Persistence/.editorconfig
index ff993b49bb..522a310bff 100644
--- a/src/ServiceControl.Audit.Persistence/.editorconfig
+++ b/src/ServiceControl.Audit.Persistence/.editorconfig
@@ -2,3 +2,9 @@
# Justification: ServiceControl app has no synchronization context
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.Audit.UnitTests/.editorconfig b/src/ServiceControl.Audit.UnitTests/.editorconfig
index 5f68a610b3..b0c4497648 100644
--- a/src/ServiceControl.Audit.UnitTests/.editorconfig
+++ b/src/ServiceControl.Audit.UnitTests/.editorconfig
@@ -2,3 +2,10 @@
# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0013.severity = none
+dotnet_diagnostic.PS0018.severity = none
diff --git a/src/ServiceControl.Audit/.editorconfig b/src/ServiceControl.Audit/.editorconfig
index ff993b49bb..c83c803ef4 100644
--- a/src/ServiceControl.Audit/.editorconfig
+++ b/src/ServiceControl.Audit/.editorconfig
@@ -2,3 +2,14 @@
# Justification: ServiceControl app has no synchronization context
dotnet_diagnostic.CA2007.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0013.severity = none
+dotnet_diagnostic.PS0017.severity = none
+dotnet_diagnostic.PS0018.severity = none
+dotnet_diagnostic.PS0019.severity = none
+dotnet_diagnostic.PS0020.severity = none
+dotnet_diagnostic.PS0021.severity = none
diff --git a/src/ServiceControl.Audit/Recoverability/DetectSuccessfulRetriesEnricher.cs b/src/ServiceControl.Audit/Recoverability/DetectSuccessfulRetriesEnricher.cs
index a97ab1af44..e3f8f5b154 100644
--- a/src/ServiceControl.Audit/Recoverability/DetectSuccessfulRetriesEnricher.cs
+++ b/src/ServiceControl.Audit/Recoverability/DetectSuccessfulRetriesEnricher.cs
@@ -34,7 +34,7 @@ public void Enrich(AuditEnricherContext context)
//and did not send the acknowledgment. We send it here to the acknowledgment queue.
var ackMessage = new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary
{
- ["ServiceControl.Retry.Successful"] = DateTimeOffsetHelper.ToWireFormattedString(DateTime.UtcNow),
+ ["ServiceControl.Retry.Successful"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow),
["ServiceControl.Retry.UniqueMessageId"] = newRetryMessageId
}, Array.Empty());
var ackOperation = new TransportOperation(ackMessage, new UnicastAddressTag(ackQueue));
diff --git a/src/ServiceControl.Config.Tests/.editorconfig b/src/ServiceControl.Config.Tests/.editorconfig
index c5410d8c02..235eef7320 100644
--- a/src/ServiceControl.Config.Tests/.editorconfig
+++ b/src/ServiceControl.Config.Tests/.editorconfig
@@ -6,3 +6,9 @@ dotnet_diagnostic.CA2007.severity = none
# Justification: Executable specifications intentionally assign properties after the
# object initializer to mirror user interaction order (e.g. typing a name after load)
dotnet_diagnostic.IDE0017.severity = none
+
+# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
+# They are scheduled work, not accepted exceptions: remove a line once this project has no
+# violations of that rule left, and never add a rule back to this list.
+dotnet_diagnostic.PS0003.severity = none
+dotnet_diagnostic.PS0013.severity = none
diff --git a/src/ServiceControl.Config/AppBootstrapper.cs b/src/ServiceControl.Config/AppBootstrapper.cs
index 4b8d0d19c6..33570c1bf6 100644
--- a/src/ServiceControl.Config/AppBootstrapper.cs
+++ b/src/ServiceControl.Config/AppBootstrapper.cs
@@ -84,6 +84,7 @@ protected override void BuildUp(object instance)
container.InjectProperties(instance);
}
+#pragma warning disable PS0027 // Overrides BootstrapperBase.OnStartup, a void-returning Application.Startup handler
protected override async void OnStartup(object sender, StartupEventArgs e)
{
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
@@ -99,6 +100,7 @@ protected override async void OnStartup(object sender, StartupEventArgs e)
Application.Current.Shutdown(-1);
}
}
+#pragma warning restore PS0027
IContainer container;
}
diff --git a/src/ServiceControl.Config/Framework/Commands/AwaitableAbstractCommand.cs b/src/ServiceControl.Config/Framework/Commands/AwaitableAbstractCommand.cs
index e6339d7925..5f7c025895 100644
--- a/src/ServiceControl.Config/Framework/Commands/AwaitableAbstractCommand.cs
+++ b/src/ServiceControl.Config/Framework/Commands/AwaitableAbstractCommand.cs
@@ -14,6 +14,7 @@ bool System.Windows.Input.ICommand.CanExecute(object parameter)
return CanExecute((T)parameter);
}
+#pragma warning disable PS0027 // ICommand.Execute returns void, so there is nothing to return the task to
async void ICommand.Execute(T obj)
{
using (StartExecuting())
@@ -23,6 +24,7 @@ async void ICommand.Execute(T obj)
}
}
+#pragma warning restore PS0027
void System.Windows.Input.ICommand.Execute(object parameter)
{
diff --git a/src/ServiceControl.Config/Framework/Commands/AwaitableDelegateCommand.cs b/src/ServiceControl.Config/Framework/Commands/AwaitableDelegateCommand.cs
index 6742a36e41..fceff09df6 100644
--- a/src/ServiceControl.Config/Framework/Commands/AwaitableDelegateCommand.cs
+++ b/src/ServiceControl.Config/Framework/Commands/AwaitableDelegateCommand.cs
@@ -22,10 +22,12 @@ bool System.Windows.Input.ICommand.CanExecute(object parameter)
return CanExecute((T)parameter);
}
+#pragma warning disable PS0027 // ICommand.Execute returns void, so there is nothing to return the task to
async void System.Windows.Input.ICommand.Execute(object parameter)
{
await ExecuteAsync((T)parameter);
}
+#pragma warning restore PS0027
public async Task ExecuteAsync(T parameter)
{
diff --git a/src/ServiceControl.Config/Framework/Rx/RxViewAware.cs b/src/ServiceControl.Config/Framework/Rx/RxViewAware.cs
index 7ad381fc88..6d97b121f0 100644
--- a/src/ServiceControl.Config/Framework/Rx/RxViewAware.cs
+++ b/src/ServiceControl.Config/Framework/Rx/RxViewAware.cs
@@ -18,7 +18,9 @@ public RxViewAware()
///
/// The view chache for this instance.
///
+#pragma warning disable PS0025 // Keyed by view context identity, so reference equality is what is wanted
protected IDictionary