From af874e502309c8010f8b743322b400f3be84c8a7 Mon Sep 17 00:00:00 2001 From: heku Date: Wed, 6 Sep 2023 23:17:05 +0800 Subject: [PATCH] Code refactor --- .../AdaptersFactoryTests.cs | 31 +++----- .../Kunet.AsyncInterceptor.PerfTests.csproj | 5 +- .../AsyncInterceptorTests.cs | 2 +- .../AsyncAdapterOfMyTask`.cs | 25 ++++++ .../AsyncInvocationOfMyTask`.cs | 17 ---- .../AsyncTaskBuilderOfMyTask`.cs | 24 ------ .../MyTaskMethodBuilder`.cs | 4 +- .../Kunet.AsyncInterceptor.Tests.csproj | 8 +- Kunet.AsyncInterceptor/AdaptersFactory.cs | 74 ------------------ .../AsyncAdapter.Factory.cs | 77 +++++++++++++++++++ Kunet.AsyncInterceptor/AsyncAdapter.cs | 51 ++++++++++++ .../AsyncAdapters/AsyncAdapterFallback.cs | 51 ++++++++++++ .../AsyncAdapters/AsyncAdapterOfTask.cs | 25 ++++++ .../AsyncAdapters/AsyncAdapterOfTask`.cs | 25 ++++++ .../AsyncAdapters/AsyncAdapterOfValueTask.cs | 25 ++++++ .../AsyncAdapters/AsyncAdapterOfValueTask`.cs | 25 ++++++ Kunet.AsyncInterceptor/AsyncInterceptor.cs | 10 +-- Kunet.AsyncInterceptor/AsyncInvocation.cs | 37 --------- .../AsyncInvocations/AsyncInvocationOfTask.cs | 18 ----- .../AsyncInvocationOfTask`.cs | 19 ----- .../AsyncInvocationOfValueTask.cs | 18 ----- .../AsyncInvocationOfValueTask`.cs | 19 ----- Kunet.AsyncInterceptor/AsyncStateMachine.cs | 16 ++-- .../AsyncTaskBuilderOfTask.cs | 25 ------ .../AsyncTaskBuilderOfTask`.cs | 25 ------ .../AsyncTaskBuilderOfValueTask.cs | 25 ------ .../AsyncTaskBuilderOfValueTask`.cs | 25 ------ Kunet.AsyncInterceptor/IAsyncAdapter.cs | 49 ++++++++++++ Kunet.AsyncInterceptor/IAsyncInvocation.cs | 16 +++- Kunet.AsyncInterceptor/IAsyncTaskBuilder.cs | 19 ----- 30 files changed, 395 insertions(+), 395 deletions(-) create mode 100644 Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncAdapterOfMyTask`.cs delete mode 100644 Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncInvocationOfMyTask`.cs delete mode 100644 Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncTaskBuilderOfMyTask`.cs delete mode 100644 Kunet.AsyncInterceptor/AdaptersFactory.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapter.Factory.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapter.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterFallback.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask`.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask.cs create mode 100644 Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask`.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncInvocation.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask`.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask`.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask`.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask.cs delete mode 100644 Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask`.cs create mode 100644 Kunet.AsyncInterceptor/IAsyncAdapter.cs delete mode 100644 Kunet.AsyncInterceptor/IAsyncTaskBuilder.cs diff --git a/Kunet.AsyncInterceptor.PerfTests/AdaptersFactoryTests.cs b/Kunet.AsyncInterceptor.PerfTests/AdaptersFactoryTests.cs index b294775..31098af 100644 --- a/Kunet.AsyncInterceptor.PerfTests/AdaptersFactoryTests.cs +++ b/Kunet.AsyncInterceptor.PerfTests/AdaptersFactoryTests.cs @@ -12,26 +12,24 @@ public class AdaptersFactoryTests public IInvocation Invocation { get; } = Mock.Of(x => x.Method.ReturnType == typeof(Task)); [Benchmark] - public void NewFactory() => AdaptersFactory.TryCreate(Invocation, out _, out _); + public void NewFactory() => AsyncAdapter.TryCreate(Invocation, out _); [Benchmark] - public void OldFactory() => LegacyFactory.TryCreate(Invocation, out _, out _); + public void OldFactory() => LegacyFactory.TryCreate(Invocation, out _); internal static class LegacyFactory { - public static bool TryCreate(IInvocation invocation, out IAsyncTaskBuilder builder, out IAsyncInvocation asyncInvocation) + public static bool TryCreate(IInvocation invocation, out IAsyncAdapter adapter) { var returnType = invocation.Method.ReturnType; if (returnType == typeof(Task)) { - builder = new AsyncTaskBuilderOfTask(); - asyncInvocation = new AsyncInvocationOfTask(invocation); + adapter = new AsyncAdapterOfTask(invocation); return true; } if (returnType == typeof(ValueTask)) { - builder = new AsyncTaskBuilderOfValueTask(); - asyncInvocation = new AsyncInvocationOfValueTask(invocation); + adapter = new AsyncAdapterOfValueTask(invocation); return true; } if (returnType.IsGenericType && returnType.GenericTypeArguments.Length == 1) @@ -40,32 +38,23 @@ public static bool TryCreate(IInvocation invocation, out IAsyncTaskBuilder build var argumentType = returnType.GenericTypeArguments[0]; if (genericType == typeof(Task<>)) { - builder = CreateAsyncTaskBuilder(typeof(AsyncTaskBuilderOfTask<>), argumentType); - asyncInvocation = CreateAsyncInvocation(typeof(AsyncInvocationOfTask<>), argumentType, invocation); + adapter = CreateAsyncAdapter(typeof(AsyncAdapterOfTask<>), argumentType, invocation); return true; } if (genericType == typeof(ValueTask<>)) { - builder = CreateAsyncTaskBuilder(typeof(AsyncTaskBuilderOfValueTask<>), argumentType); - asyncInvocation = CreateAsyncInvocation(typeof(AsyncInvocationOfValueTask<>), argumentType, invocation); + adapter = CreateAsyncAdapter(typeof(AsyncAdapterOfValueTask<>), argumentType, invocation); return true; } } - builder = null; - asyncInvocation = null; + adapter = null; return false; } - private static IAsyncTaskBuilder CreateAsyncTaskBuilder(Type genericType, Type argumentType) + private static IAsyncAdapter CreateAsyncAdapter(Type genericType, Type argumentType, IInvocation invocation) { var closedType = genericType.MakeGenericType(argumentType); - return (IAsyncTaskBuilder)Activator.CreateInstance(closedType); - } - - private static IAsyncInvocation CreateAsyncInvocation(Type genericType, Type argumentType, IInvocation invocation) - { - var closedType = genericType.MakeGenericType(argumentType); - return (IAsyncInvocation)Activator.CreateInstance(closedType, invocation); + return (IAsyncAdapter)Activator.CreateInstance(closedType, invocation); } } } \ No newline at end of file diff --git a/Kunet.AsyncInterceptor.PerfTests/Kunet.AsyncInterceptor.PerfTests.csproj b/Kunet.AsyncInterceptor.PerfTests/Kunet.AsyncInterceptor.PerfTests.csproj index 4d287f5..c0cc655 100644 --- a/Kunet.AsyncInterceptor.PerfTests/Kunet.AsyncInterceptor.PerfTests.csproj +++ b/Kunet.AsyncInterceptor.PerfTests/Kunet.AsyncInterceptor.PerfTests.csproj @@ -9,9 +9,8 @@ - - - + + diff --git a/Kunet.AsyncInterceptor.Tests/AsyncInterceptorTests.cs b/Kunet.AsyncInterceptor.Tests/AsyncInterceptorTests.cs index 1582506..28a38f6 100644 --- a/Kunet.AsyncInterceptor.Tests/AsyncInterceptorTests.cs +++ b/Kunet.AsyncInterceptor.Tests/AsyncInterceptorTests.cs @@ -42,7 +42,7 @@ public async Task InterceptByManyReturnValueFormattersTest() public async Task InterceptCustomTaskLikeReturnValueExample() { // MyTask is an example custom task-like type - AdaptersFactory.Register(typeof(MyTask<>), typeof(AsyncTaskBuilderOfMyTask<>), typeof(AsyncInvocationOfMyTask<>)); + AsyncAdapter.Register(typeof(MyTask<>), typeof(AsyncAdapterOfMyTask<>)); var target = Mock.Of(x => x.GetTaskLikeType() == new MyTask("value") diff --git a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncAdapterOfMyTask`.cs b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncAdapterOfMyTask`.cs new file mode 100644 index 0000000..cc2896c --- /dev/null +++ b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncAdapterOfMyTask`.cs @@ -0,0 +1,25 @@ +using Castle.DynamicProxy; + +namespace Kunet.AsyncInterceptor.Tests; + +// You must provide this to set AsyncResult from Invocation.ReturnValue +// You must provide this to adapt your custom TaskMethodBuilder to IAsyncTaskBuilder + +internal sealed class AsyncAdapterOfMyTask : AsyncAdapter +{ + private readonly MyTaskMethodBuilder _builder = MyTaskMethodBuilder.Create(); + + public AsyncAdapterOfMyTask(IInvocation invocation) : base(invocation) => Task = _builder.Task; + + protected override async ValueTask SetAsyncResult() => AsyncResult = await (MyTask)Invocation.ReturnValue; + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) => _builder.Start(ref stateMachine); + + public override void SetException(Exception ex) => _builder.SetException(ex); + + public override void SetResult(object result) => _builder.SetResult((T)result); + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncInvocationOfMyTask`.cs b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncInvocationOfMyTask`.cs deleted file mode 100644 index 51e64c0..0000000 --- a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncInvocationOfMyTask`.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Castle.DynamicProxy; - -namespace Kunet.AsyncInterceptor.Tests; - -// You must provide this to set AsyncResult from Invocation.ReturnValue - -internal sealed class AsyncInvocationOfMyTask : AsyncInvocation -{ - public AsyncInvocationOfMyTask(IInvocation invocation) : base(invocation) - { - } - - protected override async ValueTask SetAsyncResult() - { - AsyncResult = await (MyTask)Invocation.ReturnValue; - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncTaskBuilderOfMyTask`.cs b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncTaskBuilderOfMyTask`.cs deleted file mode 100644 index dd52c26..0000000 --- a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/AsyncTaskBuilderOfMyTask`.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor.Tests; - -// You must provide this to adapt your custom TaskMethodBuilder to IAsyncTaskBuilder - -public sealed class AsyncTaskBuilderOfMyTask : IAsyncTaskBuilder -{ - private readonly MyTaskMethodBuilder _builder = MyTaskMethodBuilder.Create(); - - public AsyncTaskBuilderOfMyTask() => Task = _builder.Task; - - public object Task { get; } - - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => _builder.Start(ref stateMachine); - - public void SetException(Exception ex) => _builder.SetException(ex); - - public void SetResult(object result) => _builder.SetResult((T)result); - - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/MyTaskMethodBuilder`.cs b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/MyTaskMethodBuilder`.cs index 6bd391a..d57f5d1 100644 --- a/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/MyTaskMethodBuilder`.cs +++ b/Kunet.AsyncInterceptor.Tests/CustomTaskLikeReturnValueExample/MyTaskMethodBuilder`.cs @@ -14,9 +14,7 @@ public class MyTaskMethodBuilder public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => stateMachine.MoveNext(); -#pragma warning disable IDE0060 // Remove unused parameter - public void SetStateMachine(IAsyncStateMachine stateMachine) -#pragma warning restore IDE0060 // Remove unused parameter + public void SetStateMachine(IAsyncStateMachine _) { } diff --git a/Kunet.AsyncInterceptor.Tests/Kunet.AsyncInterceptor.Tests.csproj b/Kunet.AsyncInterceptor.Tests/Kunet.AsyncInterceptor.Tests.csproj index 31d3cff..791794f 100644 --- a/Kunet.AsyncInterceptor.Tests/Kunet.AsyncInterceptor.Tests.csproj +++ b/Kunet.AsyncInterceptor.Tests/Kunet.AsyncInterceptor.Tests.csproj @@ -9,10 +9,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Kunet.AsyncInterceptor/AdaptersFactory.cs b/Kunet.AsyncInterceptor/AdaptersFactory.cs deleted file mode 100644 index c454e89..0000000 --- a/Kunet.AsyncInterceptor/AdaptersFactory.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Castle.DynamicProxy; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -public static class AdaptersFactory -{ - private static readonly MethodInfo CreateValueTupleMethod; - private static readonly Dictionary> Cache = new(); - private static readonly Dictionary GenericTypesRegistration = new(); - - static AdaptersFactory() - { - CreateValueTupleMethod = typeof(ValueTuple).GetMethods(BindingFlags.Public | BindingFlags.Static) - .First(m => m.GetParameters().Length == 2) - .MakeGenericMethod(typeof(IAsyncTaskBuilder), typeof(IAsyncInvocation)); - - Register(x => (new AsyncTaskBuilderOfTask(), new AsyncInvocationOfTask(x))); - Register(x => (new AsyncTaskBuilderOfValueTask(), new AsyncInvocationOfValueTask(x))); - Register(typeof(Task<>), typeof(AsyncTaskBuilderOfTask<>), typeof(AsyncInvocationOfTask<>)); - Register(typeof(ValueTask<>), typeof(AsyncTaskBuilderOfValueTask<>), typeof(AsyncInvocationOfValueTask<>)); - } - - public static void Register(Func factory) - => Cache[typeof(T)] = factory; - - public static void Register(Type genericReturnType, Type genericAsyncTaskBuilderType, Type genericAsyncInvocationType) - => GenericTypesRegistration[genericReturnType] = (genericAsyncTaskBuilderType, genericAsyncInvocationType); - - public static bool TryCreate(IInvocation invocation, out IAsyncTaskBuilder builder, out IAsyncInvocation asyncInvocation) - { - var returnType = invocation.Method.ReturnType; - if (Cache.TryGetValue(returnType, out var factory)) - { - (builder, asyncInvocation) = factory.Invoke(invocation); - return true; - } - if (returnType.IsGenericType && returnType.GenericTypeArguments.Length == 1) - { - var genericType = returnType.GetGenericTypeDefinition(); - if (GenericTypesRegistration.TryGetValue(genericType, out var types)) - { - var (genericAsyncTaskBuilderType, genericAsyncInvocationType) = types; - factory = CreateFactory(genericAsyncTaskBuilderType, genericAsyncInvocationType, returnType.GenericTypeArguments); - Cache[returnType] = factory; - (builder, asyncInvocation) = factory.Invoke(invocation); - return true; - } - } - (builder, asyncInvocation) = (null, null); - return false; - } - - private static Func CreateFactory(Type builderGenericType, Type invocationGenericType, Type[] typeArguments) - { - var builderType = builderGenericType.MakeGenericType(typeArguments); - var builderCtor = builderType.GetConstructor(Type.EmptyTypes); - var newBuilder = Expression.New(builderCtor); - - var invocationType = invocationGenericType.MakeGenericType(typeArguments); - var invocationCtor = invocationType.GetConstructors().Single(); - var argument = Expression.Parameter(typeof(IInvocation)); - var newInvocation = Expression.New(invocationCtor, argument); - - var body = Expression.Call(CreateValueTupleMethod, newBuilder, newInvocation); - - return (Func)Expression.Lambda(body, argument).Compile(); - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapter.Factory.cs b/Kunet.AsyncInterceptor/AsyncAdapter.Factory.cs new file mode 100644 index 0000000..ed2443d --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapter.Factory.cs @@ -0,0 +1,77 @@ +using Castle.DynamicProxy; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +public partial class AsyncAdapter +{ + internal static readonly Dictionary> FactoryCache = new(); // Task -> (invocation => new AsyncAdapterOfTask(invocation)) + internal static readonly Dictionary OpenGenericTypesRegistration = new(); // Task -> AsyncAdapterOfTask + + static AsyncAdapter() + { + Register(x => new AsyncAdapterOfTask(x)); // Task + Register(x => new AsyncAdapterOfValueTask(x)); // ValueTask + Register(typeof(Task<>), typeof(AsyncAdapterOfTask<>)); // Task + Register(typeof(ValueTask<>), typeof(AsyncAdapterOfValueTask<>)); // ValueTask + } + + public static void Register(Func factory) => FactoryCache[typeof(T)] = factory; + + public static void Register(Type openGenericReturnType, Type openGenericAsyncAdapterType) => OpenGenericTypesRegistration[openGenericReturnType] = openGenericAsyncAdapterType; + + internal static bool TryCreate(IInvocation invocation, out AsyncAdapter adapter) + { + var returnType = invocation.Method.ReturnType; + if (FactoryCache.TryGetValue(returnType, out var factory)) + { + adapter = factory.Invoke(invocation); + return true; + } + if (returnType.IsGenericType && returnType.GenericTypeArguments.Length == 1) + { + var openGenericReturnType = returnType.GetGenericTypeDefinition(); + if (OpenGenericTypesRegistration.TryGetValue(openGenericReturnType, out var openGenericAsyncAdapterType)) + { + factory = CreateFactory(openGenericAsyncAdapterType, returnType.GenericTypeArguments); + FactoryCache[returnType] = factory; + adapter = factory.Invoke(invocation); + return true; + } + } + var builderType = + (Attribute.GetCustomAttribute(invocation.Method, typeof(AsyncMethodBuilderAttribute), false) as AsyncMethodBuilderAttribute)?.BuilderType ?? + (Attribute.GetCustomAttribute(invocation.Method.ReturnType, typeof(AsyncMethodBuilderAttribute), false) as AsyncMethodBuilderAttribute)?.BuilderType; + if (builderType is not null) + { + if (builderType.IsGenericType is false) + { + adapter = new AsyncAdapterFallback(builderType, invocation); + return true; + } + if (builderType.IsGenericType && returnType.IsGenericType && returnType.GenericTypeArguments.Length == 1) + { + builderType = builderType.MakeGenericType(returnType.GenericTypeArguments); + adapter = new AsyncAdapterFallback(builderType, invocation); + return true; + } + } + adapter = null; + return false; + } + + private static Func CreateFactory(Type openGenericReturnType, Type[] typeArguments) + { + var adapterType = openGenericReturnType.MakeGenericType(typeArguments); + var adapterCtor = adapterType.GetConstructors().Single(); + var parameter = Expression.Parameter(typeof(IInvocation)); + var newInvocation = Expression.New(adapterCtor, parameter); + + return (Func)Expression.Lambda(newInvocation, parameter).Compile(); + } +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapter.cs b/Kunet.AsyncInterceptor/AsyncAdapter.cs new file mode 100644 index 0000000..11b888a --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapter.cs @@ -0,0 +1,51 @@ +using Castle.DynamicProxy; +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +public abstract partial class AsyncAdapter : IAsyncAdapter +{ + #region IAsyncInvocation + + private readonly IInvocationProceedInfo _proceed; + + protected AsyncAdapter(IInvocation invocation) + { + Invocation = invocation; + _proceed = invocation.CaptureProceedInfo(); + } + + public IInvocation Invocation { get; } + + public object AsyncResult { get; set; } + + public async ValueTask ProceedAsync() + { + _proceed.Invoke(); // Invocation.ReturnValue = NEXT() + if (Invocation.ReturnValue is not null) + { + await SetAsyncResult().ConfigureAwait(false); // AsyncResult = await Invocation.ReturnValue + } + } + + /// + /// AsyncResult = Invocation.ReturnValue + /// + protected abstract ValueTask SetAsyncResult(); + + #endregion IAsyncInvocation + + public abstract object Task { get; } + + public abstract void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine; + + public abstract void SetResult(object result); + + public abstract void SetException(Exception exception); + + public abstract void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine; +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterFallback.cs b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterFallback.cs new file mode 100644 index 0000000..52a6e87 --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterFallback.cs @@ -0,0 +1,51 @@ +using Castle.DynamicProxy; +using System; +using System.Reflection; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +internal sealed class AsyncAdapterFallback : AsyncAdapter +{ + private readonly Type _builderType; + private readonly object _builder; + + public AsyncAdapterFallback(Type builderType, IInvocation invocation) : base(invocation) + { + _builderType = builderType; + _builder = builderType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); + Task = _builderType.GetProperty("Task", BindingFlags.Public | BindingFlags.Instance).GetValue(_builder); + } + + protected override ValueTask SetAsyncResult() + { + var awaiter = Invocation.ReturnValue.GetType().GetMethod("GetAwaiter", BindingFlags.Public | BindingFlags.Instance).Invoke(Invocation.ReturnValue, null); + AsyncResult = awaiter.GetType().GetMethod("GetResult", BindingFlags.Public | BindingFlags.Instance).Invoke(awaiter, null); + return default; + } + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) + { + var method = _builderType.GetMethod("Start", BindingFlags.Public | BindingFlags.Instance).MakeGenericMethod(stateMachine.GetType()); + method.Invoke(_builder, new object[] { stateMachine }); + } + + public override void SetResult(object result) + { + var method = _builderType.GetMethod("SetResult", BindingFlags.Public | BindingFlags.Instance); + method.Invoke(_builder, new[] { result }); + } + + public override void SetException(Exception exception) + { + _builderType.GetMethod("SetException", BindingFlags.Public | BindingFlags.Instance).Invoke(_builder, new object[] { exception }); + } + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + { + var method = _builderType.GetMethod("AwaitUnsafeOnCompleted", BindingFlags.Public | BindingFlags.Instance).MakeGenericMethod(awaiter.GetType(), stateMachine.GetType()); + method.Invoke(_builder, new object[] { awaiter, stateMachine }); + } +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask.cs b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask.cs new file mode 100644 index 0000000..45e5586 --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask.cs @@ -0,0 +1,25 @@ +using Castle.DynamicProxy; +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +internal sealed class AsyncAdapterOfTask : AsyncAdapter +{ + private readonly AsyncTaskMethodBuilder _builder = AsyncTaskMethodBuilder.Create(); + + public AsyncAdapterOfTask(IInvocation invocation) : base(invocation) => Task = _builder.Task; + + protected override ValueTask SetAsyncResult() => new((Task)Invocation.ReturnValue); + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) => _builder.Start(ref stateMachine); + + public override void SetResult(object result) => _builder.SetResult(); + + public override void SetException(Exception exception) => _builder.SetException(exception); + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask`.cs b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask`.cs new file mode 100644 index 0000000..392fa2b --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfTask`.cs @@ -0,0 +1,25 @@ +using Castle.DynamicProxy; +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +internal sealed class AsyncAdapterOfTask : AsyncAdapter +{ + private readonly AsyncTaskMethodBuilder _builder = AsyncTaskMethodBuilder.Create(); + + public AsyncAdapterOfTask(IInvocation invocation) : base(invocation) => Task = _builder.Task; + + protected override async ValueTask SetAsyncResult() => AsyncResult = await ((Task)Invocation.ReturnValue).ConfigureAwait(false); + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) => _builder.Start(ref stateMachine); + + public override void SetResult(object result) => _builder.SetResult((T)result); + + public override void SetException(Exception exception) => _builder.SetException(exception); + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask.cs b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask.cs new file mode 100644 index 0000000..ebc7d7b --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask.cs @@ -0,0 +1,25 @@ +using Castle.DynamicProxy; +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +internal sealed class AsyncAdapterOfValueTask : AsyncAdapter +{ + private readonly AsyncValueTaskMethodBuilder _builder = AsyncValueTaskMethodBuilder.Create(); + + public AsyncAdapterOfValueTask(IInvocation invocation) : base(invocation) => Task = _builder.Task; + + protected override ValueTask SetAsyncResult() => (ValueTask)Invocation.ReturnValue; + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) => _builder.Start(ref stateMachine); + + public override void SetResult(object result) => _builder.SetResult(); + + public override void SetException(Exception exception) => _builder.SetException(exception); + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask`.cs b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask`.cs new file mode 100644 index 0000000..d17936f --- /dev/null +++ b/Kunet.AsyncInterceptor/AsyncAdapters/AsyncAdapterOfValueTask`.cs @@ -0,0 +1,25 @@ +using Castle.DynamicProxy; +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Kunet.AsyncInterceptor; + +internal sealed class AsyncAdapterOfValueTask : AsyncAdapter +{ + private readonly AsyncValueTaskMethodBuilder _builder = AsyncValueTaskMethodBuilder.Create(); + + public AsyncAdapterOfValueTask(IInvocation invocation) : base(invocation) => Task = _builder.Task; + + protected override async ValueTask SetAsyncResult() => AsyncResult = await ((ValueTask)Invocation.ReturnValue).ConfigureAwait(false); + + public override object Task { get; } + + public override void Start(ref TStateMachine stateMachine) => _builder.Start(ref stateMachine); + + public override void SetResult(object result) => _builder.SetResult((T)result); + + public override void SetException(Exception exception) => _builder.SetException(exception); + + public override void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncInterceptor.cs b/Kunet.AsyncInterceptor/AsyncInterceptor.cs index 9b79c8d..907ea94 100644 --- a/Kunet.AsyncInterceptor/AsyncInterceptor.cs +++ b/Kunet.AsyncInterceptor/AsyncInterceptor.cs @@ -10,12 +10,12 @@ public abstract class AsyncInterceptor : IInterceptor { void IInterceptor.Intercept(IInvocation invocation) { - if (AdaptersFactory.TryCreate(invocation, out var builder, out var asyncInvocation)) + if (AsyncAdapter.TryCreate(invocation, out var adapter)) { - AsyncStateMachine stateMachine = new(builder, asyncInvocation, InterceptAsync); - builder.Start(ref stateMachine); - Debug.Assert(builder.Task is not null); - invocation.ReturnValue = builder.Task; + AsyncStateMachine stateMachine = new(adapter, InterceptAsync); + adapter.Start(ref stateMachine); + Debug.Assert(adapter.Task is not null); + invocation.ReturnValue = adapter.Task; } else { diff --git a/Kunet.AsyncInterceptor/AsyncInvocation.cs b/Kunet.AsyncInterceptor/AsyncInvocation.cs deleted file mode 100644 index ded30bf..0000000 --- a/Kunet.AsyncInterceptor/AsyncInvocation.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Castle.DynamicProxy; -using System.Diagnostics; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -public abstract class AsyncInvocation : IAsyncInvocation -{ - private readonly IInvocationProceedInfo _proceed; - - public AsyncInvocation(IInvocation invocation) - { - Invocation = invocation; - _proceed = invocation.CaptureProceedInfo(); - } - - public IInvocation Invocation { get; } - - public object AsyncResult { get; set; } - - public async ValueTask ProceedAsync() - { - var lastReturnValue = Invocation.ReturnValue; - try - { - _proceed.Invoke(); - Debug.Assert(Invocation.ReturnValue is not null); - await SetAsyncResult().ConfigureAwait(false); - } - finally - { - Invocation.ReturnValue = lastReturnValue; - } - } - - protected abstract ValueTask SetAsyncResult(); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask.cs b/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask.cs deleted file mode 100644 index d484751..0000000 --- a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Castle.DynamicProxy; -using System.Diagnostics; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -internal sealed class AsyncInvocationOfTask : AsyncInvocation -{ - public AsyncInvocationOfTask(IInvocation invocation) : base(invocation) - { - } - - protected override ValueTask SetAsyncResult() - { - Debug.Assert(Invocation.ReturnValue is Task); - return new ValueTask((Task)Invocation.ReturnValue); - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask`.cs b/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask`.cs deleted file mode 100644 index bc43be0..0000000 --- a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfTask`.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Castle.DynamicProxy; -using System.Diagnostics; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -internal sealed class AsyncInvocationOfTask : AsyncInvocation -{ - public AsyncInvocationOfTask(IInvocation invocation) : base(invocation) - { - } - - protected override async ValueTask SetAsyncResult() - { - Debug.Assert(Invocation.ReturnValue is Task); - var task = (Task)Invocation.ReturnValue; - AsyncResult = await task.ConfigureAwait(false); - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask.cs b/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask.cs deleted file mode 100644 index d516f08..0000000 --- a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Castle.DynamicProxy; -using System.Diagnostics; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -internal sealed class AsyncInvocationOfValueTask : AsyncInvocation -{ - public AsyncInvocationOfValueTask(IInvocation invocation) : base(invocation) - { - } - - protected override ValueTask SetAsyncResult() - { - Debug.Assert(Invocation.ReturnValue is ValueTask); - return (ValueTask)Invocation.ReturnValue; - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask`.cs b/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask`.cs deleted file mode 100644 index 047fe52..0000000 --- a/Kunet.AsyncInterceptor/AsyncInvocations/AsyncInvocationOfValueTask`.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Castle.DynamicProxy; -using System.Diagnostics; -using System.Threading.Tasks; - -namespace Kunet.AsyncInterceptor; - -internal sealed class AsyncInvocationOfValueTask : AsyncInvocation -{ - public AsyncInvocationOfValueTask(IInvocation invocation) : base(invocation) - { - } - - protected override async ValueTask SetAsyncResult() - { - Debug.Assert(Invocation.ReturnValue is ValueTask); - var valueTask = (ValueTask)Invocation.ReturnValue; - AsyncResult = await valueTask.ConfigureAwait(false); - } -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncStateMachine.cs b/Kunet.AsyncInterceptor/AsyncStateMachine.cs index 89b423d..975a82b 100644 --- a/Kunet.AsyncInterceptor/AsyncStateMachine.cs +++ b/Kunet.AsyncInterceptor/AsyncStateMachine.cs @@ -6,15 +6,13 @@ namespace Kunet.AsyncInterceptor; internal struct AsyncStateMachine : IAsyncStateMachine { - private readonly IAsyncTaskBuilder _builder; - private readonly IAsyncInvocation _invocation; + private readonly AsyncAdapter _adapter; private readonly Func _interceptAsync; private ValueTask? _interceptingTask; - public AsyncStateMachine(IAsyncTaskBuilder builder, IAsyncInvocation invocation, Func interceptAsync) + public AsyncStateMachine(AsyncAdapter adapter, Func interceptAsync) { - _builder = builder; - _invocation = invocation; + _adapter = adapter; _interceptAsync = interceptAsync; _interceptingTask = null; } @@ -23,21 +21,21 @@ public void MoveNext() { try { - _interceptingTask ??= _interceptAsync(_invocation); + _interceptingTask ??= _interceptAsync(_adapter); var awaiter = _interceptingTask.Value.GetAwaiter(); if (awaiter.IsCompleted) { awaiter.GetResult(); // throw exception if there is. - _builder.SetResult(_invocation.AsyncResult); + _adapter.SetResult(_adapter.AsyncResult); } else { - _builder.AwaitUnsafeOnCompleted(ref awaiter, ref this); + _adapter.AwaitUnsafeOnCompleted(ref awaiter, ref this); } } catch (Exception ex) { - _builder.SetException(ex); + _adapter.SetException(ex); } } diff --git a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask.cs b/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask.cs deleted file mode 100644 index b16cbe7..0000000 --- a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor; - -[DebuggerStepThrough] -internal sealed class AsyncTaskBuilderOfTask : IAsyncTaskBuilder -{ - private readonly AsyncTaskMethodBuilder _builder = AsyncTaskMethodBuilder.Create(); - - public AsyncTaskBuilderOfTask() => Task = _builder.Task; - - public object Task { get; } - - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => _builder.Start(ref stateMachine); - - public void SetResult(object result) => _builder.SetResult(); - - public void SetException(Exception exception) => _builder.SetException(exception); - - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask`.cs b/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask`.cs deleted file mode 100644 index 06afbac..0000000 --- a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfTask`.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor; - -[DebuggerStepThrough] -internal sealed class AsyncTaskBuilderOfTask : IAsyncTaskBuilder -{ - private readonly AsyncTaskMethodBuilder _builder = AsyncTaskMethodBuilder.Create(); - - public AsyncTaskBuilderOfTask() => Task = _builder.Task; - - public object Task { get; } - - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => _builder.Start(ref stateMachine); - - public void SetResult(object result) => _builder.SetResult((T)result); - - public void SetException(Exception exception) => _builder.SetException(exception); - - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask.cs b/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask.cs deleted file mode 100644 index b5f120a..0000000 --- a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor; - -[DebuggerStepThrough] -internal sealed class AsyncTaskBuilderOfValueTask : IAsyncTaskBuilder -{ - private readonly AsyncValueTaskMethodBuilder _builder = AsyncValueTaskMethodBuilder.Create(); - - public AsyncTaskBuilderOfValueTask() => Task = _builder.Task; - - public object Task { get; } - - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => _builder.Start(ref stateMachine); - - public void SetResult(object result) => _builder.SetResult(); - - public void SetException(Exception exception) => _builder.SetException(exception); - - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask`.cs b/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask`.cs deleted file mode 100644 index 5d6d054..0000000 --- a/Kunet.AsyncInterceptor/AsyncTaskBuilders/AsyncTaskBuilderOfValueTask`.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor; - -[DebuggerStepThrough] -internal sealed class AsyncTaskBuilderOfValueTask : IAsyncTaskBuilder -{ - private readonly AsyncValueTaskMethodBuilder _builder = AsyncValueTaskMethodBuilder.Create(); - - public AsyncTaskBuilderOfValueTask() => Task = _builder.Task; - - public object Task { get; } - - public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => _builder.Start(ref stateMachine); - - public void SetResult(object result) => _builder.SetResult((T)result); - - public void SetException(Exception exception) => _builder.SetException(exception); - - public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine => _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); -} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/IAsyncAdapter.cs b/Kunet.AsyncInterceptor/IAsyncAdapter.cs new file mode 100644 index 0000000..c111285 --- /dev/null +++ b/Kunet.AsyncInterceptor/IAsyncAdapter.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Kunet.AsyncInterceptor; + +internal interface IAsyncAdapter : IAsyncInvocation +{ + /// + /// Encapsulate the to be a same TASK type as the TARGET's. + /// + /// Task = { + /// await InterceptAsync() + /// { + /// // ... + /// await ProceedAsync() { AsyncResult = await NEXT Task } + /// // ... + /// } + /// return AsyncResult; + /// } + /// + /// + object Task { get; } + + /// + /// Start the , i.e. start the . + /// + /// + /// The will invoke . + /// + void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine; + + /// + /// Set the succeeded with . + /// + void SetResult(object result); + + /// + /// Set the failed with . + /// + void SetException(Exception exception); + + /// + /// Link the and together, so that when + /// completed, the . will be invoked. + /// + void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine; +} \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/IAsyncInvocation.cs b/Kunet.AsyncInterceptor/IAsyncInvocation.cs index 1fd2f9d..c25025d 100644 --- a/Kunet.AsyncInterceptor/IAsyncInvocation.cs +++ b/Kunet.AsyncInterceptor/IAsyncInvocation.cs @@ -12,18 +12,26 @@ public interface IAsyncInvocation /// /// /// - /// Do NOT use , use instead.
- /// Do NOT use , use instead. + /// Do not use , use instead.
+ /// Do not use , use instead. ///
IInvocation Invocation { get; } /// - /// Replacement of in asynchronous mode. + /// Replacement of in asynchronous mode. + /// AsyncResult = Invocation.ReturnValue + /// /// object AsyncResult { get; set; } /// - /// Replacement of in asynchronous mode. + /// Replacement of in asynchronous mode. + /// Invocation.ReturnValue = NEXT() + /// AsyncResult = Invocation.ReturnValue + /// /// + /// + /// + /// ValueTask ProceedAsync(); } \ No newline at end of file diff --git a/Kunet.AsyncInterceptor/IAsyncTaskBuilder.cs b/Kunet.AsyncInterceptor/IAsyncTaskBuilder.cs deleted file mode 100644 index fc82747..0000000 --- a/Kunet.AsyncInterceptor/IAsyncTaskBuilder.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Kunet.AsyncInterceptor; - -public interface IAsyncTaskBuilder -{ - object Task { get; } - - void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine; - - void SetResult(object result); - - void SetException(Exception exception); - - void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) - where TAwaiter : ICriticalNotifyCompletion - where TStateMachine : IAsyncStateMachine; -} \ No newline at end of file