From 71c4beb2c8a27a039608c18c38348ecbbcb4509c Mon Sep 17 00:00:00 2001 From: sakno Date: Thu, 26 Sep 2024 11:59:47 +0300 Subject: [PATCH] Added extra converts to async delegates --- src/DotNext.Tests/DelegateHelpersTests.cs | 11 ++++ src/DotNext/DelegateHelpers.cs | 73 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/DotNext.Tests/DelegateHelpersTests.cs b/src/DotNext.Tests/DelegateHelpersTests.cs index eb29ba126..108a90123 100644 --- a/src/DotNext.Tests/DelegateHelpersTests.cs +++ b/src/DotNext.Tests/DelegateHelpersTests.cs @@ -543,6 +543,17 @@ public static async Task ToAsync4() func = new Func(static (_, _) => throw new Exception()).ToAsync(); await ThrowsAsync(func.Invoke(42, 42, new(canceled: false)).AsTask); } + + [Fact] + public static async Task ToAsync5() + { + var func = Func.Identity().ToAsync(); + Equal(42, await func.Invoke(42, new(canceled: false))); + True(func.Invoke(42, new(canceled: true)).IsCanceled); + + func = new Func(static _ => throw new Exception()).ToAsync(); + await ThrowsAsync(func.Invoke(42, new(canceled: false)).AsTask); + } [Fact] public static void HideReturnValue1() diff --git a/src/DotNext/DelegateHelpers.cs b/src/DotNext/DelegateHelpers.cs index 8c9dc7aa4..aa65a3b24 100644 --- a/src/DotNext/DelegateHelpers.cs +++ b/src/DotNext/DelegateHelpers.cs @@ -126,6 +126,43 @@ private static ValueTask Invoke(this Action action, T arg, CancellationTok return task; } + /// + /// Converts function to async delegate. + /// + /// Synchronous function. + /// The type of the argument to be passed to the action. + /// The type of the return value. + /// The asynchronous function that wraps . + /// is . + public static Func> ToAsync(this Func action) + { + ArgumentNullException.ThrowIfNull(action); + + return action.Invoke; + } + + private static ValueTask Invoke(this Func action, T arg, CancellationToken token) + { + ValueTask task; + if (token.IsCancellationRequested) + { + task = ValueTask.FromCanceled(token); + } + else + { + try + { + task = new(action.Invoke(arg)); + } + catch (Exception e) + { + task = ValueTask.FromException(e); + } + } + + return task; + } + /// /// Converts action to async delegate. /// @@ -161,6 +198,42 @@ private static ValueTask Invoke(this Action action, CancellationToken token) return task; } + + /// + /// Converts function to async delegate. + /// + /// The type of the return value. + /// Synchronous function. + /// The asynchronous function that wraps . + /// is . + public static Func> ToAsync(this Func func) + { + ArgumentNullException.ThrowIfNull(func); + + return func.Invoke; + } + + private static ValueTask Invoke(this Func func, CancellationToken token) + { + ValueTask task; + if (token.IsCancellationRequested) + { + task = ValueTask.FromCanceled(token); + } + else + { + try + { + task = new(func.Invoke()); + } + catch (Exception e) + { + task = ValueTask.FromException(e); + } + } + + return task; + } /// /// Converts action to async delegate.