/// <summary> /// *SLOW* Perform the actual call here to the target control object. /// Control calls are more complex, since they get executed on the control's /// Invoke() thread, and to do this, we need the actual delegate instance. /// </summary> protected object CallControlInvoke(Control target, out Exception exception) { if (Matrix.Framework.SuperPool.Core.SuperPool.CallContextEnabled) { SuperPoolCallContext.CurrentCall = this; } object result = null; exception = null; try { ControlInvokeDelegate delegateInstance = delegate(MethodInfo methodInfo, Control controlTarget, object[] parameters) { return(FastInvokeHelper.CachedInvoke(methodInfo, controlTarget, parameters)); }; // Synchronously perform the invocation. result = target.Invoke(delegateInstance, new object[] { MethodInfoLocal, target, Parameters }); } catch (Exception ex) { exception = ex; } if (Matrix.Framework.SuperPool.Core.SuperPool.CallContextEnabled) { SuperPoolCallContext.CurrentCall = null; } return(result); }
/// <summary> /// Perform the actual call here to the target object. /// </summary> public object Call(object target, bool autoControlInvoke, out Exception exception) { if (autoControlInvoke && target is Control) { return(CallControlInvoke((Control)target, out exception)); } if (Matrix.Framework.SuperPool.Core.SuperPool.CallContextEnabled) { SuperPoolCallContext.CurrentCall = this; } exception = null; object result = null; try { // This call is very fast since it uses the static cache in the helper. result = FastInvokeHelper.CachedInvoke(MethodInfoLocal, target, Parameters); // This conventional invoke gives around 1 Million executions per second load by itself. // TODO: optimization can be done using the DelegateTypeCache from CallControlInvoke(), // since it uses the actual strongly typed delegates already. //result = MethodInfo.Invoke(target, Parameters); } catch (Exception ex) { exception = ex; } if (Matrix.Framework.SuperPool.Core.SuperPool.CallContextEnabled) { SuperPoolCallContext.CurrentCall = null; } return(result); }