protected override object Invoke(MethodInfo targetMethod, object[] args) { Log.Debug("[MethodProxy.Invoke] " + (new MethodCallInfo() { Name = targetMethod.Name, Args = args.ToList() }).ToString()); bool IsIInvokeProxy = _invokeType == InvokeType.Proxy || _invokeType == InvokeType.ProxyFunc; IInvokerProxy invoker; switch (_invokeType) { case InvokeType.Proxy: invoker = _invokerProxy; break; case InvokeType.ProxyFunc: invoker = GetIInvokerProxyFunc(); break; default: invoker = null; break; } if (IsIInvokeProxy || BeforeInvoke != null) { BeforeInvokeEventArgs beforeArgs = new BeforeInvokeEventArgs() { MethodInfo = targetMethod, Args = args, }; BeforeInvoke?.Invoke(this, beforeArgs); invoker?.BeforeInvoke(this, beforeArgs); if (beforeArgs.Handled) { return(beforeArgs.FakeResult); } } object result; if (IsIInvokeProxy) { result = invoker.Invoke(targetMethod, args); } else if (_invokeType == InvokeType.Object) { result = targetMethod.Invoke(_invokeObject, args); } else { throw new Exception("InvokeProxy: unknown InvokeType"); } if (result is Task task) { if (targetMethod.ReturnType.IsGenericType) { Type type = targetMethod.ReturnType.GetGenericArguments()[0]; if (TypeHelper.IsType(task, typeof(Task <object>))) { result = TaskHelper.ConvertTaskObject((Task <object>)task, type); } else { // e.g. UnwrapPromise<object> var generic_task = TaskHelper.ConvertTaskReturnObject(task); result = TaskHelper.ConvertTaskObject(generic_task, type); } } else { Task.Run(async() => await task); result = Task.CompletedTask; } } TypeHelper.AssertType(result, targetMethod.ReturnType); if (IsIInvokeProxy || AfterInvoke != null) { AfterInvokeEventArgs afterArgs = new AfterInvokeEventArgs() { MethodInfo = targetMethod, Args = args, Result = result, }; AfterInvoke?.Invoke(this, afterArgs); invoker?.AfterInvoke(this, afterArgs); } return(result); }