/// <summary> /// Creates a proxy for an actor component object and places it in an existing actor /// </summary> internal CreatorInterfaceInvocationHandler(ObjectCreator <IActorComponent> creator, IActor rootObject, ProxyFactory proxyFactory) { // We need to lock on the root when using an existing actor ThreadPool.QueueUserWorkItem( delegate { Hooking.ActorCallWrapper(() => { IActorComponent newObject = creator(); ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, rootObject, proxyFactory); m_RealInvocationHandler = temp; m_FinishedEvent.Set(); }); }); }
/// <summary> /// Creates an interceptor for an object that doesn't exist yet. /// /// This will trigger its asynchronous construction. /// </summary> public CreatorInterfaceInvocationHandler(ObjectCreator <IActor> creator, ProxyFactory proxyFactory) { ThreadPool.QueueUserWorkItem( delegate { Hooking.ActorCallWrapper( () => { IActor newObject = creator(); ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, newObject, proxyFactory); m_RealInvocationHandler = temp; m_FinishedEvent.Set(); }); }); }
public override void InvokeHappened(object[] parameterValues) { // A method has been called on the proxy Hooking.BeforeActorCallQueued(m_Root.GetType(), m_TargetMethod, parameterValues); ConvertParameters(parameterValues); if (!m_RootIsWPFControl.HasValue) { // Find whether this actor is a wpf control m_RootIsWPFControl = IsWPFControl(m_Root); if (m_RootIsWPFControl.Value) { m_RootIsControl = true; } } if (!m_RootIsControl.HasValue) { // Find whether this actor is a winforms control m_RootIsControl = IsWinformsControl(m_Root); } Queue <Action> queueForThisObject; lock (s_JobQueues) { if (!s_JobQueues.TryGetValue(m_Root, out queueForThisObject)) { queueForThisObject = new Queue <Action>(); s_JobQueues[m_Root] = queueForThisObject; } } lock (queueForThisObject) { queueForThisObject.Enqueue(() => BaseInvokeHappened(parameterValues)); } if (m_RootIsControl.Value) { // It's a control, use reflection to call begininvoke on it object dispatcher; if (m_RootIsWPFControl.Value) { // It's a wpf control, use reflection to get its dispatcher to call begininvoke on that dispatcher = m_Root.GetType().GetProperty("Dispatcher").GetGetMethod().Invoke(m_Root, new object[0]); } else { // Winforms controls are their own dispatcher dispatcher = m_Root; } dispatcher.GetType().GetMethod("BeginInvoke", new[] { typeof(Delegate), typeof(object[]) }).Invoke( dispatcher, new object[] { (Action)(() => Hooking.ActorCallWrapper(() => RunNextQueueItem(m_Root, queueForThisObject))), new object[0] }); } else { // Just a standard actor - add the task to the work queue ThreadPool.QueueUserWorkItem( delegate { Hooking.ActorCallWrapper(() => { lock (m_Root) { RunNextQueueItem(m_Root, queueForThisObject); } }); }); } }