Пример #1
0
 /// <summary>
 /// Enables progress polling.
 /// Use <see cref="CurrentProgress"/> to retrieve the task's current progress.
 /// Returns the current progress task, so that methods may be chained.
 /// </summary>
 public ProgressTask EnablePolling(int maximumDepth)
 {
     this.pollingEnabled          = true;
     this.currentProgressAccessed = true;
     this.currentProgress         = new ProgressChangedInfo(new ProgressInfo(0f, null, null), null);
     this.maximumDepth            = (ProgressDepth)maximumDepth;
     return(this);
 }
Пример #2
0
        /// <summary>
        /// Calculates the current progress,
        /// and invokes the callback for the
        /// current task and all parent tasks.
        /// </summary>
        private void OnProgressChanged(object currentStepArg)
        {
            // First, an optimization:
            // we might not need to calculate progress at all,
            // if no one is listening:
            ProgressDepth depth = 0;
            var           task  = this;

            while (true)
            {
                // Determine if we've reached the bottom of the stack or the maximum depth:
                if (task == null || task.maximumDepth < depth)
                {
                    // No one's listening this deep!
                    // Skip calculations.
                    return;
                }

                // Check for a callback:
                if (task.progressChangedCallback != null)
                {
                    break;
                }
                // Check for polling:
                if (task.pollingEnabled)
                {
                    if (task.currentProgressAccessed || (int)depth < task.currentProgress.CurrentDepth)
                    {
                        // Polling is enabled and is ready for a new CurrentProgress.
                        break;
                    }
                }

                // Traverse the progress stack:
                depth++;
                task = task.parent;
            }


            depth = 0;
            task  = this;

            var taskProgress = 0.0f;
            var allProgress  = new Stack <ProgressInfo>();

            while (true)
            {
                // Calculate the task's progress:
                if (task.isEnded) // 100%!
                {
                    taskProgress = 1.0f;
                }
                else
                {
                    taskProgress = task.calculator.CalculateProgress(taskProgress);
                }

                allProgress.Push(new ProgressInfo(taskProgress, task.taskKey, task.taskArg));

                // Raise events or update Polling:
                ProgressChangedInfo progressChangedInfo = null;
                // Raise the event if necessary:
                if (task.progressChangedCallback != null)
                {
                    progressChangedInfo = new ProgressChangedInfo(allProgress, currentStepArg);
                    task.progressChangedCallback(progressChangedInfo);
                }
                // Update the CurrentProgress so that it can be used for polling.
                if (task.pollingEnabled)
                {
                    // If the current CurrentProgress hasn't been accessed,
                    // then we will only update if the new item is higher priority (lower depth):
                    if (task.currentProgressAccessed || (int)depth < task.currentProgress.CurrentDepth)
                    {
                        if (progressChangedInfo == null)
                        {
                            progressChangedInfo = new ProgressChangedInfo(allProgress, currentStepArg);
                        }

                        task.currentProgressAccessed = false;
                        task.currentProgress         = progressChangedInfo;
                    }
                }

                // Traverse the progress stack:
                depth++;
                task = task.parent;

                // Determine if we've reached the bottom of the stack or the maximum depth:
                if (task == null || task.maximumDepth < depth)
                {
                    break;
                }
            }
        }