diff --git a/BasicNodes/Functions/Sleep.cs b/BasicNodes/Functions/Sleep.cs index bc21e560..2a80206c 100644 --- a/BasicNodes/Functions/Sleep.cs +++ b/BasicNodes/Functions/Sleep.cs @@ -23,12 +23,15 @@ public class Sleep : Node /// public override bool FailureNode => true; + private CancellationTokenSource _cancellationTokenSource; + [NumberInt(1)] [Range(1, 3_600_000)] [DefaultValue(1000)] public int Milliseconds{ get; set; } + /// public override int Execute(NodeParameters args) { if (Milliseconds < 1 || Milliseconds > 3_600_000) @@ -36,7 +39,60 @@ public class Sleep : Node args.Logger.ELog("Milliseconds must be between 1 and 3,600,000"); return -1; } - Thread.Sleep(Milliseconds); - return 1; + + // Initialize a new CancellationTokenSource for this execution. + _cancellationTokenSource = new CancellationTokenSource(); + var cancellationToken = _cancellationTokenSource.Token; + + try + { + // Start the task to run the sleep operation with cancellation support. + var _executionTask = Task.Run(() => RunSleep(cancellationToken, args)); + // Wait for the task to complete or be canceled, using the cancellation token. + _executionTask.Wait(cancellationToken); + + // Return 1 to indicate the operation completed successfully. + return 1; + } + catch (OperationCanceledException) + { + // Handle cancellation of the operation. + args.Logger.ELog("Execution was canceled."); + // Return -1 to indicate that the operation was canceled. + return -1; + } + } + + /// + /// Runs the sleep operation asynchronously, supporting cancellation. + /// + /// The token that allows for cancellation of the operation. + /// The parameters passed into the node execution, including logging capabilities. + /// A task that represents the asynchronous operation. + private async Task RunSleep(CancellationToken cancellationToken, NodeParameters args) + { + try + { + // Use Task.Delay with the cancellation token to simulate sleeping and support cancellation. + await Task.Delay(Milliseconds, cancellationToken); + } + catch (OperationCanceledException) + { + // Catch the cancellation and rethrow to propagate it to the caller. + throw; + } + } + + /// + public override Task Cancel() + { + // Trigger the cancellation of the running task if it exists. + if (_cancellationTokenSource != null) + { + _cancellationTokenSource.Cancel(); + } + + // Return a completed task to indicate the cancellation action has been requested. + return Task.CompletedTask; } }