Exemple #1
0
        static bool WaitInternal(int?msTimeout, Func <bool> condition)
        {
            bool timedOut = false;

            Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);
            DispatcherFrame frame = new DispatcherFrame();

            DispatcherHookEventHandler onOperationCompleted = null;
            Action popFrame = () => {
                frame.Continue = false;
                Dispatcher.CurrentDispatcher.Hooks.OperationCompleted -= onOperationCompleted;
            };

            onOperationCompleted = (s, ea) => {
                if (condition())
                {
                    popFrame();
                }
            };

            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => {
                Dispatcher.CurrentDispatcher.Hooks.OperationCompleted += onOperationCompleted;
            }));

            if (msTimeout != null)
            {
                PumpTimer.DoLater(msTimeout.Value, () => {
                    timedOut = true;
                    popFrame();
                });
            }

            Dispatcher.PushFrame(frame);
            return(!timedOut);
        }
        internal void EmitOperationPriorityChanged(DispatcherOperation op)
        {
            DispatcherHookEventHandler prio = this.OperationPriorityChanged;

            if (prio != null)
            {
                prio(this.owner, new DispatcherHookEventArgs(op));
            }
        }
        internal void EmitOperationAborted(DispatcherOperation op)
        {
            DispatcherHookEventHandler aborted = this.OperationAborted;

            if (aborted != null)
            {
                aborted(this.owner, new DispatcherHookEventArgs(op));
            }
        }
        internal void EmitOperationCompleted(DispatcherOperation op)
        {
            DispatcherHookEventHandler completed = this.OperationCompleted;

            if (completed != null)
            {
                completed(this.owner, new DispatcherHookEventArgs(op));
            }
        }
Exemple #5
0
        internal void RaiseOperationAborted(Dispatcher dispatcher, DispatcherOperation operation)
        {
            DispatcherHookEventHandler operationAborted = _operationAborted;

            if (operationAborted != null)
            {
                operationAborted(dispatcher, new DispatcherHookEventArgs(operation));
            }
        }
Exemple #6
0
        internal void EmitOperationPosted(DispatcherOperation op)
        {
            DispatcherHookEventHandler posted = OperationPosted;

            if (posted != null)
            {
                posted(owner, new DispatcherHookEventArgs(op));
            }
        }
Exemple #7
0
        private void Watchdog()
        {
            while (!_shuttingDown)
            {
                _idleReached = false;
                Thread.Sleep(MaxBusy);
                if (!_idleReached && !Debugger.IsAttached)
                {
                    //Make sure we don't see our own post monitoring!
                    //TODO: should we sample more than once?
#pragma warning disable 612,618
                    var thread = _dispatcher.Thread;
                    thread.Suspend();
                    var timedOutTrace = new StackTrace(thread, false);
                    thread.Resume();
#pragma warning restore 612,618

                    var postedOperations = new BlockingCollection <DispatcherOperation>();
                    DispatcherHookEventHandler hooksOnOperationPosted = null;
                    const int maxOperationToLog = 100;
                    hooksOnOperationPosted = delegate(object sender, DispatcherHookEventArgs e)
                    {
                        if (postedOperations.Count < maxOperationToLog)
                        {
                            postedOperations.Add(e.Operation);
                        }
                        else
                        {
                            _dispatcher.Hooks.OperationPosted -= hooksOnOperationPosted;
                        }
                    };
                    _dispatcher.Hooks.OperationPosted += hooksOnOperationPosted;

                    var sb = new StringBuilder();
                    sb.AppendLine("Dispatcher is blocked:");
                    sb.AppendLine(timedOutTrace.ToString());
                    Thread.Sleep(SamplePeriod); //wait for some posts

                    var nameGetter = typeof(DispatcherOperation).GetProperty("Name", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true);
                    foreach (var operation in postedOperations)
                    {
                        sb.AppendLine(nameGetter.Invoke(operation, new object[] { }).ToString());
                    }
                    var message = sb.ToString();
                    Logger.Error(message);
                    throw new OpenGammaException(message); //Should be caught by general error handler
                }
            }
        }
        public static bool WaitOneAndPump(this WaitHandle handle, int millisecondsTimeout)
        {
            using (var operationPendingMre = new ManualResetEvent(false))
            {
                bool      result = false;
                Exception error  = null;

                var startTick = Environment.TickCount;

                var handles = new[] {
                    handle.SafeWaitHandle.DangerousGetHandle(),
                    operationPendingMre.SafeWaitHandle.DangerousGetHandle()
                };

                var dispatcher = Dispatcher.CurrentDispatcher;

                var frame = new DispatcherFrame();

                var getTimeout = (Timeout.Infinite == millisecondsTimeout) ?
                                 new Func <uint>(() => INFINITE) :
                                 new Func <uint>(() => (uint)Math.Max(0,
                                                                      millisecondsTimeout + startTick - Environment.TickCount));

                DispatcherHookEventHandler onOperationPosted = (s, e) =>
                {
                    // this may occur on a random thread,
                    // trigger a helper event and
                    // unblock MsgWaitForMultipleObjectsEx inside onDispatcherInactive
                    operationPendingMre.Set();
                };

                DispatcherHookEventHandler onOperationCompleted = (s, e) =>
                {
                    // this should occur on the Dispather thread
                    Debug.Assert(Thread.CurrentThread == dispatcher.Thread);

                    // do an instant handle check
                    var nativeResult = WaitForSingleObject(handles[0], 0);
                    if (nativeResult == WAIT_OBJECT_0)
                    {
                        result = true;
                    }
                    else if (nativeResult == WAIT_ABANDONED_0)
                    {
                        error = new AbandonedMutexException(-1, handle);
                    }
                    else if (getTimeout() == 0)
                    {
                        result = false;
                    }
                    else if (nativeResult == WAIT_TIMEOUT)
                    {
                        return;
                    }
                    else
                    {
                        error = new InvalidOperationException("WaitForSingleObject");
                    }

                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };

                EventHandler onDispatcherInactive = (s, e) =>
                {
                    operationPendingMre.Reset();

                    // wait for the handle or a message
                    var timeout = getTimeout();

                    var nativeResult = MsgWaitForMultipleObjectsEx(
                        (uint)handles.Length, handles,
                        timeout,
                        QS_EVENTMASK,
                        MWMO_INPUTAVAILABLE);

                    if (nativeResult == WAIT_OBJECT_0)
                    {
                        result = true;     // handle signalled
                    }
                    else if (nativeResult == WAIT_TIMEOUT)
                    {
                        result = false;     // timed-out
                    }
                    else if (nativeResult == WAIT_ABANDONED_0)
                    {
                        error = new AbandonedMutexException(-1, handle);
                    }
                    else if (nativeResult != WAIT_OBJECT_0 + 1 && nativeResult != WAIT_OBJECT_0 + 2)
                    {
                        error = new InvalidOperationException("MsgWaitForMultipleObjectsEx");
                    }
                    else
                    {
                        // a Windows message or a Dispatcher operation is pending
                        if (timeout == 0)
                        {
                            result = false;     // timed-out
                        }
                        else
                        {
                            return;
                        }
                    }

                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };

                dispatcher.Hooks.OperationCompleted += onOperationCompleted;
                dispatcher.Hooks.OperationPosted    += onOperationPosted;
                dispatcher.Hooks.DispatcherInactive += onDispatcherInactive;

                try
                {
                    // onDispatcherInactive will be called on the new frame,
                    // as soon as Dispatcher becomes idle
                    Dispatcher.PushFrame(frame);
                }
                finally
                {
                    dispatcher.Hooks.OperationCompleted -= onOperationCompleted;
                    dispatcher.Hooks.OperationPosted    -= onOperationPosted;
                    dispatcher.Hooks.DispatcherInactive -= onDispatcherInactive;
                }

                if (error != null)
                {
                    throw error;
                }

                return(result);
            }
        }
Exemple #9
0
        public static bool WaitOneAndPump(this WaitHandle handle, int millisecondsTimeout)
        {
            using (var operationPendingMre = new ManualResetEvent(false))
            {
                var result = false;

                var startTick = Environment.TickCount;

                var dispatcher = Dispatcher.CurrentDispatcher;

                var frame = new DispatcherFrame();

                var handles = new[] {
                    handle.SafeWaitHandle.DangerousGetHandle(),
                    operationPendingMre.SafeWaitHandle.DangerousGetHandle()
                };

                Action idleAction = () => operationPendingMre.Set();

                DispatcherOperation idleOperation = null;

                Func <uint> getTimeout;
                if (Timeout.Infinite == millisecondsTimeout)
                {
                    getTimeout = () => INFINITE;
                }
                else
                {
                    getTimeout = () => (uint)Math.Max(0, millisecondsTimeout + startTick - Environment.TickCount);
                }

                DispatcherHookEventHandler onOperationPosted = (s, e) =>
                {
                    // this may occur on a random thread,
                    // trigger a helper event and
                    // unblock MsgWaitForMultipleObjectsEx inside onDispatcherInactive
                    operationPendingMre.Set();
                };

                DispatcherHookEventHandler onOperationCompleted = (s, e) =>
                {
                    // this should be fired on the Dispather thread
                    Debug.Assert(Thread.CurrentThread == dispatcher.Thread);

                    // do an instant handle check
                    var nativeResult = WaitForSingleObject(handles[0], 0);
                    if (nativeResult == WAIT_OBJECT_0)
                    {
                        result = true;
                    }
                    else if (nativeResult == WAIT_ABANDONED_0)
                    {
                        throw new AbandonedMutexException(-1, handle);
                    }
                    else if (getTimeout() == 0)
                    {
                        result = false;
                    }
                    else if (nativeResult == WAIT_TIMEOUT)
                    {
                        return;
                    }
                    else
                    {
                        throw new InvalidOperationException("WaitForSingleObject");
                    }

                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };

                EventHandler onDispatcherInactive = (s, e) =>
                {
                    operationPendingMre.Reset();

                    // wait for the handle or a message
                    var timeout = getTimeout();

                    var nativeResult = MsgWaitForMultipleObjectsEx(
                        (uint)handles.Length, handles,
                        timeout,
                        QS_EVENTMASK,
                        MWMO_INPUTAVAILABLE);

                    if (nativeResult == WAIT_OBJECT_0)
                    {
                        // handle signalled
                        result = true;
                    }
                    else if (nativeResult == WAIT_TIMEOUT)
                    {
                        // timed out
                        result = false;
                    }
                    else if (nativeResult == WAIT_ABANDONED_0)
                    {
                        // abandonded mutex
                        throw new AbandonedMutexException(-1, handle);
                    }
                    else if (nativeResult == WAIT_OBJECT_0 + 1)
                    {
                        // operation posted from another thread, yield to the frame loop
                        return;
                    }
                    else if (nativeResult == WAIT_OBJECT_0 + 2)
                    {
                        // a Windows message
                        if (getTimeout() > 0)
                        {
                            // message pending, yield to the frame loop
                            idleOperation.Abort();
                            idleOperation = dispatcher.BeginInvoke(idleAction, DispatcherPriority.ApplicationIdle);
                            return;
                        }

                        // timed out
                        result = false;
                    }
                    else
                    {
                        // unknown result
                        throw new InvalidOperationException("MsgWaitForMultipleObjectsEx");
                    }

                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };

                dispatcher.Hooks.OperationCompleted += onOperationCompleted;
                dispatcher.Hooks.OperationPosted    += onOperationPosted;
                dispatcher.Hooks.DispatcherInactive += onDispatcherInactive;

                idleOperation = dispatcher.BeginInvoke(idleAction, DispatcherPriority.ApplicationIdle);
                try
                {
                    // onDispatcherInactive will be called on the new frame,
                    // as soon as Dispatcher becomes idle
                    Dispatcher.PushFrame(frame);
                }
                finally
                {
                    idleOperation.Abort();
                    dispatcher.Hooks.OperationCompleted -= onOperationCompleted;
                    dispatcher.Hooks.OperationPosted    -= onOperationPosted;
                    dispatcher.Hooks.DispatcherInactive -= onDispatcherInactive;
                }

                return(result);
            }
        }