Browse Source

refactor: Reduce reflection calls when using HandlerInvoker (#5241)

Changes `HandlerInvoker` to avoid reflecting for every message when handling arity=2 `IHandler<,>` instances, by moving it out of the final generated delegate.
tags/magentic-one-cli-v0.2.3
Jacob Alber GitHub 1 year ago
parent
commit
2e83d7244a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 10 deletions
  1. +3
    -2
      dotnet/src/Microsoft.AutoGen/Core/BaseAgent.cs
  2. +6
    -8
      dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs

+ 3
- 2
dotnet/src/Microsoft.AutoGen/Core/BaseAgent.cs View File

@@ -70,9 +70,10 @@ public abstract class BaseAgent : IAgent, IHostableAgent
Dictionary<Type, HandlerInvoker> invokers = new();
foreach (Type interface_ in candidateInterfaces)
{
MethodInfo? maybeHandle = interface_.GetMethod(nameof(IHandle<object>.HandleAsync), BindingFlags.Instance | BindingFlags.Public);
MethodInfo handleAsync = interface_.GetMethod(nameof(IHandle<object>.HandleAsync), BindingFlags.Instance | BindingFlags.Public)
?? throw new InvalidOperationException($"No handler method found for interface {interface_.FullName}");

HandlerInvoker invoker = new(maybeHandle ?? throw new InvalidOperationException($"No handler method found for interface {interface_.FullName}"), this);
HandlerInvoker invoker = new(handleAsync, this);
invokers.Add(interface_.GetGenericArguments()[0], invoker);
}



+ 6
- 8
dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs View File

@@ -42,19 +42,17 @@ public class HandlerInvoker
return null;
};
}
else if (
methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>)
)
else if (methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))
{
MethodInfo typeEraseAwait = typeof(HandlerInvoker)
.GetMethod(nameof(TypeEraseAwait), BindingFlags.NonPublic | BindingFlags.Static)!
.MakeGenericMethod(methodInfo.ReturnType.GetGenericArguments()[0]);

getResultAsync = async
(object? message, MessageContext messageContext) =>
{
object valueTask = invocation(message, messageContext)!;

object? typelessValueTask = typeof(HandlerInvoker)
.GetMethod(nameof(TypeEraseAwait), BindingFlags.NonPublic | BindingFlags.Static)!
.MakeGenericMethod(methodInfo.ReturnType.GetGenericArguments()[0])
.Invoke(null, new object[] { valueTask });
object? typelessValueTask = typeEraseAwait.Invoke(null, new object[] { valueTask });

Debug.Assert(typelessValueTask is ValueTask<object?>);



Loading…
Cancel
Save