From 5a0c0cc93b6b6aae4a196b10ee7656ab787ab6bf Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Tue, 21 Oct 2025 17:39:20 -0500 Subject: [PATCH 1/3] fix: Ensure PlatformScheduleAction order is preserved In Android/iOS these action are run on the main thread whereas in netstandard they are run in a threadpool and are not guaranteed to be run in order when we don't wait for the result. --- .../src/PlatformSpecific/AsyncScheduler.netstandard.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs index ddaf028e..02f869fa 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs @@ -7,7 +7,15 @@ internal static partial class AsyncScheduler { private static void PlatformScheduleAction(Action a) { - Task.Run(a); + try + { + // Wait for the task to complete to ensure that actions are executed in the correct order. + Task.Run(a).Wait(); + } + catch (Exception) + { + // Swallow exceptions to prevent them from propagating to the caller. + } } } } From bb4906939b280cba738dc9155adf36350a83bc20 Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Thu, 23 Oct 2025 14:00:56 +0000 Subject: [PATCH 2/3] try linking actions to avoid wait --- .../PlatformSpecific/AsyncScheduler.netstandard.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs index 02f869fa..30f1cd18 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs @@ -5,17 +5,13 @@ namespace LaunchDarkly.Sdk.Client.PlatformSpecific { internal static partial class AsyncScheduler { + private static volatile Task _lastScheduledTask = Task.CompletedTask; + private static void PlatformScheduleAction(Action a) { - try - { - // Wait for the task to complete to ensure that actions are executed in the correct order. - Task.Run(a).Wait(); - } - catch (Exception) - { - // Swallow exceptions to prevent them from propagating to the caller. - } + // Chain the new action to run after the previous one completes + // This ensures actions run in order while maintaining fire-and-forget behavior + _lastScheduledTask = _lastScheduledTask.ContinueWith(_ => a(), TaskContinuationOptions.ExecuteSynchronously); } } } From e0169d4152f27c01a856fb6f8dedd68e1f7a69bf Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Mon, 27 Oct 2025 13:57:48 +0000 Subject: [PATCH 3/3] use the default and run the continuation task async --- .../client/src/PlatformSpecific/AsyncScheduler.netstandard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs index 30f1cd18..98aa97e7 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/AsyncScheduler.netstandard.cs @@ -11,7 +11,7 @@ private static void PlatformScheduleAction(Action a) { // Chain the new action to run after the previous one completes // This ensures actions run in order while maintaining fire-and-forget behavior - _lastScheduledTask = _lastScheduledTask.ContinueWith(_ => a(), TaskContinuationOptions.ExecuteSynchronously); + _lastScheduledTask = _lastScheduledTask.ContinueWith(_ => a()); } } }