public void CancelAllAsync()
        {
            if (!_supportsCancellation)
            {
                throw new InvalidOperationException("This instance of the QueuedBackgroundWorker does not support cancellation.");
            }

            lock (_collectionsLock)
            {
                _cancelAllPending = true;

                foreach (object key in _userStateToOperationMap.Keys)
                {
                    OperationInfo opInfo = _userStateToOperationMap[key] as OperationInfo;

                    if (opInfo != null)
                    {
                        opInfo.OperationRequest.Cancel();
                    }
                }
            }
        }
        public void RunWorkerAsync(object userState)
        {
            if (userState == null)
            {
                throw new ArgumentNullException("userState cannot be null.");
            }

            int prevCount;
            OperationRequest opRequest = new OperationRequest(userState, OperationHandler);
            OperationInfo    opInfo    = new OperationInfo(opRequest);

            lock (_collectionsLock)
            {
                if (_userStateToOperationMap.ContainsKey(userState))
                {
                    throw new InvalidOperationException("The specified userKey has already been used to identify a pending operation.  Each userState parameter must be unique.");
                }

                //Make a note of the current pending queue size.  If it's zero at this point,
                //we'll need to kick off an operation.

                prevCount = _operationQueue.Count;

                // Place the new work item on the queue & also in the userState-to-OperationInfo map.
                //
                _operationQueue.Enqueue(opInfo);
                _userStateToOperationMap[userState] = opInfo;
            }

            if (prevCount == 0)
            {
                // We just queued up the first item - kick off the operation.
                //
                opRequest.OperationHandler.BeginInvoke(opInfo, OperationHandlerDone, opInfo);
            }
        }
        private RunWorkerCompletedEventArgsWithUserState OperationHandler(OperationInfo opInfo)
        {
            object          userState = opInfo.OperationRequest.UserState;
            DoWorkEventArgs eventArgs = new DoWorkEventArgs(userState);

            try
            {
                RaiseDoWorkEventFromAsyncContext(eventArgs);

                if (eventArgs.Cancel)
                {
                    opInfo.OperationRequest.Cancel(); // For the sake of completeness.
                    return(new RunWorkerCompletedEventArgsWithUserState(null, null, true, userState));
                }
                else
                {
                    return(new RunWorkerCompletedEventArgsWithUserState(eventArgs.Result, null, false, userState));
                }
            }
            catch (Exception err)
            {
                return(new RunWorkerCompletedEventArgsWithUserState(null, err, false, userState));
            }
        }
 private void RaiseWorkCompletedEventFromAsyncContext(OperationInfo opInfo)
 {
     opInfo.OperationRequest.AsyncOperation.PostOperationCompleted(RaiseWorkCompletedEventFromClientContext, opInfo);
 }
        private void RaiseProgressChangedEventFromAsyncContext(int percentComplete, object userState, OperationInfo opInfo)
        {
            ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs(percentComplete, userState);

            opInfo.OperationRequest.AsyncOperation.Post(RaiseProgressChangedEventFromClientContext, eventArgs);
        }