Example #1
0
        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);
                        }
                    });
                });
            }
        }