2

Where do i get the ISynchronizeInvoke so i can sync against UI thread?

System.Timers.Timer gTimer; gTimer.SynchronizingObject;

EKS
  • 5,543
  • 6
  • 44
  • 60
  • Are you mixing WinForms and WPF, or new to WPF? – Tim Lloyd Aug 01 '10 at 22:12
  • 2
    You also have DispatcherTimer For clean WPF timer http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx " Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the Dispatcher" – Kristoffer Schroeder Aug 01 '10 at 22:55

1 Answers1

5

This may work,

gTimer.SynchronizingObject = new DispatcherWinFormsCompatAdapter(this.Dispatcher));

internal class DispatcherWinFormsCompatAdapter : ISynchronizeInvoke
  {
       #region IAsyncResult implementation
      private class DispatcherAsyncResultAdapter : IAsyncResult
        {
            private DispatcherOperation m_op;
             private object m_state;

            public DispatcherAsyncResultAdapter(DispatcherOperation operation)
            {
                m_op = operation;
            }

            public DispatcherAsyncResultAdapter(DispatcherOperation operation, object state)
               : this(operation)
            {
                m_state = state;
           }

            public DispatcherOperation Operation
            {
                get { return m_op; }
            }

            #region IAsyncResult Members

            public object AsyncState
            {
                get { return m_state; }
            }

           public WaitHandle AsyncWaitHandle
            {
                get { return null; }
            }

            public bool CompletedSynchronously
            {
                get { return false; }
            }

            public bool IsCompleted
            {
                get { return m_op.Status == DispatcherOperationStatus.Completed; }
            }

            #endregion
        }
        #endregion
        private Dispatcher m_disp;
        public DispatcherWinFormsCompatAdapter(Dispatcher dispatcher)
        {
            m_disp = dispatcher;
        }
        #region ISynchronizeInvoke Members

        public IAsyncResult BeginInvoke(Delegate method, object[] args)
        {
            if (args != null && args.Length > 1)
            {
                object[] argsSansFirst = GetArgsAfterFirst(args);
                DispatcherOperation op = m_disp.BeginInvoke(DispatcherPriority.Normal, method, args[0], argsSansFirst);
                return new DispatcherAsyncResultAdapter(op);
            }
            else
            {
                if (args != null)
                {
                    return new DispatcherAsyncResultAdapter(m_disp.BeginInvoke(DispatcherPriority.Normal, method, args[0]));
                }
                else
                {
                    return new DispatcherAsyncResultAdapter(m_disp.BeginInvoke(DispatcherPriority.Normal, method));
                }
            }
        }

        private static object[] GetArgsAfterFirst(object[] args)
        {
            object[] result = new object[args.Length - 1];
            Array.Copy(args, 1, result, 0, args.Length - 1);
            return result;
        }

        public object EndInvoke(IAsyncResult result)
        {
            DispatcherAsyncResultAdapter res = result as DispatcherAsyncResultAdapter;
            if (res == null)
                throw new InvalidCastException();

            while (res.Operation.Status != DispatcherOperationStatus.Completed || res.Operation.Status == DispatcherOperationStatus.Aborted)
            {
                Thread.Sleep(50);
            }

            return res.Operation.Result;
        }

        public object Invoke(Delegate method, object[] args)
       {
           if (args != null && args.Length > 1)
           {
               object[] argsSansFirst = GetArgsAfterFirst(args);
               return m_disp.Invoke(DispatcherPriority.Normal, method, args[0], argsSansFirst);
           }
           else
           {
               if (args != null)
               {
                   return m_disp.Invoke(DispatcherPriority.Normal, method, args[0]);
               }
               else
               {
                   return m_disp.Invoke(DispatcherPriority.Normal, method);
               }
           }
       }

       public bool InvokeRequired
       {
           get { return m_disp.Thread != Thread.CurrentThread; }
       }

       #endregion
   }
  • Thank you that worked perfectly. Much more code then i expected, thank you for the solution – EKS Aug 01 '10 at 22:15