From 60da9a3667aeb959f9857b290fc985f868904168 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 11 Mar 2026 10:48:48 +0100 Subject: [PATCH 1/2] [tests] Detect when we couldn't create a second background session. When disposing an NSUrlSessionHandler backed by a background NSUrlSession and immediately creating a new handler with the same background session identifier, the new session could fail with 'Task created in a session that has been invalidated'. This happened because InvalidateAndCancel() is asynchronous - it marks the session for invalidation but doesn't wait for it to complete. Apple reuses the same native session object for background sessions with the same identifier, so creating a new session before invalidation completes returns the already-invalidated session. Fix by detecting this scenario in the test, and marking the test as inconclusive. Fixes https://github.com/dotnet/macios/issues/24376 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System.Net.Http/NSUrlSessionHandlerTest.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs b/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs index 628c45094e57..a206f6ce3c5b 100644 --- a/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs +++ b/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs @@ -59,6 +59,24 @@ public void DisposeAndRecreateBackgroundSessionHandler () IgnoreIfExceptionDueToBackgroundServiceInUseByAnotherProcess (ex); TestRuntime.IgnoreInCIIfBadNetwork (ex); + if (ex is ObjCException && ex.ToString ().Contains ("Task created in a session that has been invalidated")) { + // When disposing an NSUrlSessionHandler backed by a background NSUrlSession + // and immediately creating a new handler with the same background session + // identifier, the new session can fail with 'Task created in a session + // that has been invalidated'. + // + // This happens because InvalidateAndCancel() is asynchronous - it marks + // the session for invalidation but doesn't wait for it to complete. Apple + // reuses the same native session object for background sessions with the + // same identifier, so creating a new session before invalidation completes + // returns the already-invalidated session. + // + // There are a couple of fixes: + // * Add a Thread.Sleep before creating the second NSUrlSessionHandler - but this will slow down every test run, + // * Wait for the session to become invalid in NSUrlSessionHandler (add a 'DidBecomeInvalid' implementation, and wait for that in Dispose) - which may unnecessarily slow down working code. + // * Detect this scenario here, and just mark the test as inconclusive. The test does something somewhat unusual (create two background sessions with the same identifier in quick succession), so this seems like the best approach for now. + Assert.Inconclusive ("The previous background session wasn't fully invalidated before we tried to create a new background (with the same identifier)"); + } Assert.IsNull (ex, "Second request exception"); } From 1d42a2a1108f597f8544510292e6bca839ae9b13 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 12 Mar 2026 16:12:03 +0100 Subject: [PATCH 2/2] Update tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs b/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs index a206f6ce3c5b..34e018063694 100644 --- a/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs +++ b/tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs @@ -75,7 +75,7 @@ public void DisposeAndRecreateBackgroundSessionHandler () // * Add a Thread.Sleep before creating the second NSUrlSessionHandler - but this will slow down every test run, // * Wait for the session to become invalid in NSUrlSessionHandler (add a 'DidBecomeInvalid' implementation, and wait for that in Dispose) - which may unnecessarily slow down working code. // * Detect this scenario here, and just mark the test as inconclusive. The test does something somewhat unusual (create two background sessions with the same identifier in quick succession), so this seems like the best approach for now. - Assert.Inconclusive ("The previous background session wasn't fully invalidated before we tried to create a new background (with the same identifier)"); + Assert.Inconclusive ("The previous background session wasn't fully invalidated before we tried to create a new background session (with the same identifier)"); } Assert.IsNull (ex, "Second request exception"); }