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); }
// // 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(); } } } }