예제 #1
0
        public static void PushFrame(DispatcherFrame frame)
        {
            if (frame == null)
            {
                throw new ArgumentNullException();
            }
            Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher;

            if (currentDispatcher._hasShutdownFinished)
            {
                throw new InvalidOperationException();
            }
            currentDispatcher.PushFrameImpl(frame);
        }
예제 #2
0
        //
        // instance implementation of PushFrame
        private void PushFrameImpl(DispatcherFrame frame)
        {
            var prevFrame = this._currentFrame;

            this._frameDepth++;
            try {
                this._currentFrame = frame;

                while (frame.Continue)
                {
                    DispatcherOperation op = null;
                    var aborted            = false;

                    //
                    // Dequeue the next operation if appropriate
                    if (this._queue.Count > 0)
                    {
                        op = (DispatcherOperation)this._queue.Dequeue();

                        //Must check aborted flag inside lock because
                        //user program could call op.Abort() between
                        //here and before the call to Invoke()
                        aborted = op.Status == DispatcherOperationStatus.Aborted;
                    }

                    if (op != null)
                    {
                        if (!aborted)
                        {
                            // Invoke the operation:
                            Debug.Assert(op._status == DispatcherOperationStatus.Pending);

                            // Mark this operation as executing.
                            op._status = DispatcherOperationStatus.Executing;

                            op._result = null;

                            try {
                                op._result = op._method(op._args);
                            }
                            catch (Exception e) {
                                if (this._finalExceptionHandler == null ||
                                    !this._finalExceptionHandler(op, e))
                                {
                                    throw;
                                }
                            }

                            // Mark this operation as completed.
                            op._status = DispatcherOperationStatus.Completed;

                            // Raise the Completed so anyone who is waiting will wake up.
                            op.OnCompleted();
                        }
                    }
                    else
                    {
                        this._event.WaitOne();
                    }
                }
            }
            finally {
                this._frameDepth--;

                this._currentFrame = prevFrame;

                // If this was the last frame to exit after a quit, we
                // can now dispose the dispatcher.
                if (this._frameDepth == 0)
                {
                    if (this._hasShutdownStarted)
                    {
                        ShutdownImpl();
                    }
                }
            }
        }