コード例 #1
0
        private void ShutdownImpl()
        {
            Debug.Assert(_hasShutdownStarted);
            Debug.Assert(!_hasShutdownFinished);

            // Call the ShutdownFinished event before we actually mark ourselves
            // as shut down.  This is so the handlers can actaully do work
            // when they get this event without throwing exceptions.
            EventHandler e = ShutdownFinished;

            if (e != null)
            {
                e(this, EventArgs.Empty);
            }

            // Mark this dispatcher as shut down.  Attempts to BeginInvoke
            // or Invoke will result in an exception.
            _hasShutdownFinished = true;

            lock (_instanceLock)
            {
                // Now that the queue is off-line, abort all pending operations,
                // including inactive ones.
                while (_queue.Count > 0)
                {
                    DispatcherOperation operation = (DispatcherOperation)_queue.Dequeue();

                    if (operation != null)
                    {
                        operation.Abort();
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        ///     Executes the specified delegate synchronously with the specified
        ///     arguments, on the thread that the Dispatcher was created on.
        /// </summary>
        /// <param name="timeout">
        ///     The maximum amount of time to wait for the operation to complete.
        /// </param>
        /// <param name="method">
        ///     A delegate to a method that takes parameters of the same number
        ///     and type that are contained in the args parameter.
        /// </param>
        /// <param name="args">
        ///     An object to pass as the argument to the given method.
        ///     This can be null if no arguments are needed.
        /// </param>
        /// <returns>
        ///     The return value from the delegate being invoked, or null if
        ///     the delegate has no return value or if the operation was aborted.
        /// </returns>
        public object Invoke(TimeSpan timeout, DispatcherOperationCallback method, object args)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            object result = null;

            DispatcherOperation op = BeginInvoke(method, args);

            if (op != null)
            {
                op.Wait(timeout);

                if (op.Status == DispatcherOperationStatus.Completed)
                {
                    result = op.Result;
                }
                else if (op.Status == DispatcherOperationStatus.Aborted)
                {
                    // Hm, someone aborted us.  Maybe the dispatcher got
                    // shut down on us?  Just return null.
                }
                else
                {
                    // We timed out, just abort the op so that it doesn't
                    // invoke later.
                    //
                    // Note the race condition: if this is a foreign thread,
                    // it is possible that the dispatcher thread could actually
                    // dispatch the operation between the time our Wait()
                    // call returns and we get here.  In the case the operation
                    // will actually be dispatched, but we will return failure.
                    //
                    // We recognize this but decide not to do anything about it,
                    // as this is a common problem is multi-threaded programming.
                    op.Abort();
                }
            }

            return(result);
        }