Example #1
0
        /// <summary>
        /// Callers of this method create an instance of AsyncTask derived 
        /// class and call this method to schedule the task for execution.
        /// </summary>
        /// <param name="asyncTask">The task to execute asynchronously.</param>
        /// 
        internal void ScheduleForExecution(AsyncTask asyncTask)
        {
            // When an AsyncTask is scheduled for execution during a test, it 
            // executes on the context of the thread that runs the unit test 
            // case (in a regular headless test case this is the unit test 
            // background thread; in a recorded test this is the main ui thread).
            // 
            if (DynamoModel.IsTestMode)
            {
                asyncTask.MarkTaskAsScheduled();
                ProcessTaskInternal(asyncTask);
                return;
            }

            lock (taskQueue)
            {
                taskQueue.Add(asyncTask); // Append new task to the end
                asyncTask.MarkTaskAsScheduled(); // Update internal time-stamp.

                // Mark the queue as being updated. This causes the next call
                // to "ProcessNextTask" method to post process the task queue.
                taskQueueUpdated = true;

                // Signal task availability so scheduler picks it up.
                waitHandles[(int)EventIndex.TaskAvailable].Set();
            }
        }
        private void NotifyTaskStateChanged(AsyncTask task, TaskState state)
        {
            var stateChangedHandler = TaskStateChanged;
            if (stateChangedHandler == null)
                return; // No event handler, bail.

            var e = new TaskStateChangedEventArgs(task, state);
            stateChangedHandler(this, e);
        }
 private static void ProcessTaskInternal(AsyncTask asyncTask)
 {
     try
     {
         asyncTask.Execute(); // Internally sets the ExecutionStartTime
         asyncTask.HandleTaskCompletion(null); // Completed successfully.
     }
     catch (Exception exception)
     {
         // HandleTaskCompletion internally sets the ExecutionEndTime time,
         // it also invokes the registered callback Action if there is one.
         // 
         asyncTask.HandleTaskCompletion(exception);
     }
 }
        private void ProcessTaskInternal(AsyncTask asyncTask)
        {
            NotifyTaskStateChanged(asyncTask, TaskState.ExecutionStarting);

            var executionState = asyncTask.Execute()
                ? TaskState.ExecutionCompleted
                : TaskState.ExecutionFailed;

            NotifyTaskStateChanged(asyncTask, executionState);
            asyncTask.HandleTaskCompletion();
            NotifyTaskStateChanged(asyncTask, TaskState.CompletionHandled);
        }
Example #5
0
 private void OnPreviewGraphCompleted(AsyncTask asyncTask)
 {
     var updateTask = asyncTask as PreviewGraphAsyncTask;
     if (updateTask != null)
     {
         var nodeGuids = updateTask.previewGraphData;
         var deltaComputeStateArgs = new DeltaComputeStateEventArgs(nodeGuids,graphExecuted);
         OnSetNodeDeltaState(deltaComputeStateArgs);               
     }            
 }
        protected override AsyncTask.TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var theOtherTask = otherTask as UpdateGraphAsyncTask;
            if (theOtherTask == null)
                return base.CanMergeWithCore(otherTask);

            // Comparing to another UpdateGraphAsyncTask, verify 
            // that they are updating a similar set of nodes.

            if ((graphSyncData != null && 
                graphSyncData.DeletedSubtrees != null && 
                graphSyncData.DeletedSubtrees.Any()) ||
                (theOtherTask.graphSyncData != null &&
                 theOtherTask.graphSyncData.DeletedSubtrees != null && 
                 theOtherTask.graphSyncData.DeletedSubtrees.Any()))
                return TaskMergeInstruction.KeepBoth;

            // Other node is either equal or a superset of this task
            if (ModifiedNodes.All(x => theOtherTask.ModifiedNodes.Contains(x)))
            {
                return TaskMergeInstruction.KeepOther;
            }

            // This node is a superset of the other
            if (theOtherTask.ModifiedNodes.All(x => ModifiedNodes.Contains(x)))
            {
                return TaskMergeInstruction.KeepThis;
            }

            // They're different, keep both
            return TaskMergeInstruction.KeepBoth;
        }
Example #7
0
        private void OnNodeValueQueried(AsyncTask asyncTask)
        {
            lock (cachedMirrorDataMutex)
            {
                var task = asyncTask as QueryMirrorDataAsyncTask;
                cachedMirrorData = task.MirrorData;
            }

            RaisePropertyChanged("IsUpdated");
        }
        protected override TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var theOtherTask = otherTask as UpdateRenderPackageAsyncTask;
            if (theOtherTask == null)
                return base.CanMergeWithCore(otherTask);

            // If the two UpdateRenderPackageAsyncTask are for different nodes,
            // then there is no comparison to be made, keep both the tasks.
            // 
            if (nodeGuid != theOtherTask.nodeGuid)
                return TaskMergeInstruction.KeepBoth;

            // Comparing to another NotifyRenderPackagesReadyAsyncTask, the one 
            // that gets scheduled more recently stay, while the earlier one 
            // gets dropped. If this task has a higher tick count, keep this.
            // 
            if (ScheduledTime.TickCount > theOtherTask.ScheduledTime.TickCount)
                return TaskMergeInstruction.KeepThis;

            return TaskMergeInstruction.KeepOther; // Otherwise, keep the other.
        }
Example #9
0
 internal TaskStateChangedEventArgs(AsyncTask task, State state)
 {
     Task         = task;
     CurrentState = state;
 }
Example #10
0
 protected virtual int CompareCore(AsyncTask otherTask)
 {
     return(0); // Having the same priority by default.
 }
Example #11
0
        protected override int CompareCore(AsyncTask otherTask)
        {
            // PrioritizedAsyncTask always come before InconsequentialAsyncTask.
            if (otherTask is InconsequentialAsyncTask)
                return -1;

            // It is not compared with another PrioritizedAsyncTask, fall back.
            var task = otherTask as PrioritizedAsyncTask;
            if (task == null)
                return base.CompareCore(otherTask);

            // Priority 1 tasks always come before priority 2 tasks.
            return CurrPriority - task.CurrPriority;
        }
Example #12
0
        protected override AsyncTask.TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var theOtherTask = otherTask as UpdateGraphAsyncTask;
            if (theOtherTask == null)
                return base.CanMergeWithCore(otherTask);

            if (theOtherTask.Contains(this))
                return TaskMergeInstruction.KeepOther;
            else if (this.Contains(theOtherTask)) 
                return TaskMergeInstruction.KeepThis;
            else
                return TaskMergeInstruction.KeepBoth;
        }
Example #13
0
        protected override AsyncTask.TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var theOtherTask = otherTask as UpdateGraphAsyncTask;
            if (theOtherTask == null)
                return TaskMergeInstruction.KeepBoth;

            return TaskMergeInstruction.KeepOther;
        }
Example #14
0
 /// <summary>
 /// Call this method to determine the relative priority of two AsyncTask
 /// objects. DynamoScheduler makes use of this method to determine the
 /// order in which AsyncTask objects are sorted in its internal task queue.
 /// </summary>
 /// <param name="otherTask">A task to compare this task with.</param>
 /// <returns>Returns -1 if this AsyncTask object should be processed
 /// before the other AsyncTask; returns 1 if this AsyncTask object should
 /// be processed after the other AsyncTask; or 0 if both AsyncTask objects
 /// have the same priority and can be processed in the current order.
 /// </returns>
 ///
 internal int Compare(AsyncTask otherTask)
 {
     return(ReferenceEquals(this, otherTask) ? 0 : CompareCore(otherTask));
 }
Example #15
0
 /// <summary>
 /// This method is called by DynamoScheduler when it compacts the task
 /// queue. The result of this call indicates if either of the tasks in
 /// comparison should be dropped from the task queue, or both should be
 /// kept. Tasks that are discarded during this phase will not be executed.
 /// </summary>
 /// <param name="otherTask">Another task to compare with.</param>
 /// <returns>Returns the comparison result. See Comparison enumeration
 /// for details of the possible values.</returns>
 ///
 internal TaskMergeInstruction CanMergeWith(AsyncTask otherTask)
 {
     return(ReferenceEquals(this, otherTask)
         ? TaskMergeInstruction.KeepBoth
         : CanMergeWithCore(otherTask));
 }
Example #16
0
 /// <summary>
 ///     Upon completion of the task, invoke the specified action
 /// </summary>
 /// <returns>An IDisposable representing the event subscription</returns>
 internal static IDisposable Then(this AsyncTask task, AsyncTaskCompletedHandler action)
 {
     task.Completed += action;
     return(Disposable.Create(() => task.Completed -= action));
 }
Example #17
0
 protected virtual TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
 {
     return(TaskMergeInstruction.KeepBoth); // Keeping both tasks by default.
 }
Example #18
0
        protected override TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var task = otherTask as InconsequentialAsyncTask;
            if (task == null)
                return base.CanMergeWithCore(otherTask);

            // The comparison only keeps the task that carries a bigger punch.
            if (Punch > task.Punch)
                return TaskMergeInstruction.KeepThis;

            return TaskMergeInstruction.KeepOther;
        }
Example #19
0
        /// <summary>
        /// An ISchedulerThread implementation calls this method so scheduler
        /// starts to process the next task in the queue, if there is any. Note
        /// that this method is meant to process only one task in queue. The
        /// implementation of ISchedulerThread is free to call this method again
        /// in a fashion that matches its task fetching behavior.
        /// </summary>
        /// <param name="waitIfTaskQueueIsEmpty">This parameter is only used if
        /// the task queue is empty at the time this method is invoked. When the
        /// task queue becomes empty, setting this to true will cause this call
        /// to block until either the next task becomes available, or when the
        /// scheduler is requested to shutdown.</param>
        /// <returns>This method returns true if the task queue is not empty, or
        /// false otherwise. Note that this method returns false when scheduler
        /// begins to shutdown, even when the task queue is not empty.</returns>
        ///
        public bool ProcessNextTask(bool waitIfTaskQueueIsEmpty)
        {
            AsyncTask nextTask = null;
            IEnumerable <AsyncTask> droppedTasks = null;

            lock (taskQueue)
            {
                if (taskQueueUpdated)
                {
                    // The task queue has been updated since the last time
                    // a task was processed, it might need compacting.
                    droppedTasks = CompactTaskQueue();

                    ReprioritizeTasksInQueue();
                    taskQueueUpdated = false;
                }

                if (taskQueue.Count > 0)
                {
                    nextTask = taskQueue[0];
                    taskQueue.RemoveAt(0);
                }
                else
                {
                    // No more task in queue, reset wait handle.
                    waitHandles[(int)EventIndex.TaskAvailable].Reset();
                }
            }

            if (droppedTasks != null)
            {
                // Only notify listeners of dropping tasks here instead of
                // within CompactTaskQueue method. This way the lock on task
                // queue will not be held up for a prolonged period of time.
                //
                foreach (var droppedTask in droppedTasks)
                {
                    NotifyTaskStateChanged(droppedTask, TaskState.Discarded);
                }
            }

            if (nextTask != null)
            {
                ProcessTaskInternal(nextTask);
                return(true); // This method should be called again.
            }

            // If there's no more task and wait is not desired...
            if (!waitIfTaskQueueIsEmpty)
            {
                return(false); // The task queue is now empty.
            }
            // Block here if ISchedulerThread requests to wait.
            // ReSharper disable once CoVariantArrayConversion
            int index = WaitHandle.WaitAny(waitHandles);

            // If a task becomes available, this method returns true to indicate
            // that an immediate call may be required (subjected to the decision
            // of the ISchedulerThread's implementation). In the event that the
            // scheduler is shutting down, then this method returns false.
            //
            return(index == ((int)EventIndex.TaskAvailable));
        }
Example #20
0
        protected override int CompareCore(AsyncTask otherTask)
        {
            // PrioritizedAsyncTask always come before InconsequentialAsyncTask.
            if (otherTask is PrioritizedAsyncTask)
                return 1;

            // InconsequentialAsyncTask are always treated equal.
            return base.CompareCore(otherTask);
        }
Example #21
0
        /// <summary>
        /// This callback method is invoked in the context of ISchedulerThread 
        /// when UpdateGraphAsyncTask is completed.
        /// </summary>
        /// <param name="task">The original UpdateGraphAsyncTask instance.</param>
        /// 
        private static void OnUpdateGraphCompleted(AsyncTask task)
        {
            var updateTask = task as UpdateGraphAsyncTask;
            var messages = new Dictionary<Guid, string>();

            // Runtime warnings take precedence over build warnings.
            foreach (var warning in updateTask.RuntimeWarnings)
            {
                var message = string.Join("\n", warning.Value);
                messages.Add(warning.Key, message);
            }

            foreach (var warning in updateTask.BuildWarnings)
            {
                // If there is already runtime warnings for 
                // this node, then ignore the build warnings.
                if (messages.ContainsKey(warning.Key))
                    continue;

                var message = string.Join("\n", warning.Value);
                messages.Add(warning.Key, message);
            }

            var workspace = updateTask.TargetedWorkspace;
            foreach (var message in messages)
            {
                var guid = message.Key;
                var node = workspace.Nodes.FirstOrDefault(n => n.GUID == guid);
                if (node == null)
                    continue;

                node.Warning(message.Value); // Update node warning message.
            }
        }
Example #22
0
 internal void WriteExecutionLog(AsyncTask asyncTask)
 {
     var name = asyncTask.GetType().Name;
     Results.Add(string.Format("{0}: {1}", name, serialNumber));
 }
Example #23
0
        /// <summary>
        /// This callback method is invoked in the context of ISchedulerThread 
        /// when UpdateGraphAsyncTask is completed.
        /// </summary>
        /// <param name="task">The original UpdateGraphAsyncTask instance.</param>
        /// 
        private void OnUpdateGraphCompleted(AsyncTask task)
        {
            var updateTask = task as UpdateGraphAsyncTask;
            var messages = new Dictionary<Guid, string>();

            // Runtime warnings take precedence over build warnings.
            foreach (var warning in updateTask.RuntimeWarnings)
            {
                var message = string.Join("\n", warning.Value.Select(w => w.Message));
                messages.Add(warning.Key, message);
            }

            foreach (var warning in updateTask.BuildWarnings)
            {
                // If there is already runtime warnings for 
                // this node, then ignore the build warnings.
                if (messages.ContainsKey(warning.Key))
                    continue;

                var message = string.Join("\n", warning.Value.Select(w => w.Message));
                messages.Add(warning.Key, message);
            }

            var workspace = updateTask.TargetedWorkspace;
            foreach (var message in messages)
            {
                var guid = message.Key;
                var node = workspace.Nodes.FirstOrDefault(n => n.GUID == guid);
                if (node == null)
                    continue;

                node.Warning(message.Value); // Update node warning message.
            }

            // This method is guaranteed to be called in the context of 
            // ISchedulerThread (for Revit's case, it is the idle thread).
            // Dispatch the failure message display for execution on UI thread.
            // 
            if (task.Exception != null && (DynamoModel.IsTestMode == false))
            {
                Action showFailureMessage = () => 
                    Utils.DisplayEngineFailureMessage(this, task.Exception);

                OnRequestDispatcherBeginInvoke(showFailureMessage);
            }

            // Notify listeners (optional) of completion.
            OnEvaluationCompleted(this, EventArgs.Empty);
        }
Example #24
0
        public void TestTaskQueuePreProcessing05()
        {
            var schedulerThread = new SampleSchedulerThread();
            var scheduler = new DynamoScheduler(schedulerThread, false);

            // Start scheduling a bunch of tasks.
            var asyncTasks = new AsyncTask[]
            {
                new PrioritizedAsyncTask(scheduler, 1), 
                new InconsequentialAsyncTask(scheduler, 100),
            };

            var results = new List<string>();
            foreach (SampleAsyncTask asyncTask in asyncTasks)
            {
                asyncTask.InitializeWithResultList(results);
                scheduler.ScheduleForExecution(asyncTask);
            }

            schedulerThread.GetSchedulerToProcessTasks();

            // Drops all InconsequentialAsyncTask and leave behind one.
            // Kept all PrioritizedAsyncTask instances and sorted them.
            Assert.AreEqual(2, results.Count);
            Assert.AreEqual("PrioritizedAsyncTask: 1", results[0]);
            Assert.AreEqual("InconsequentialAsyncTask: 100", results[1]);
        }
Example #25
0
 /// <summary>
 /// This event handler is invoked when UpdateRenderPackageAsyncTask is 
 /// completed, at which point the render packages (specific to this node) 
 /// become available. Since this handler is called off the UI thread, the 
 /// '_renderPackages' must be guarded against concurrent access.
 /// </summary>
 /// <param name="asyncTask">The instance of UpdateRenderPackageAsyncTask
 /// that was responsible of generating the render packages.</param>
 /// 
 private void OnRenderPackageUpdateCompleted(AsyncTask asyncTask)
 {
     lock (RenderPackagesMutex)
     {
         var task = asyncTask as UpdateRenderPackageAsyncTask;
         renderPackages.Clear();
         renderPackages.AddRange(task.RenderPackages);
         HasRenderPackages = renderPackages.Any();
     }
 }
Example #26
0
        public void TestTaskStateChangedEventHandling()
        {
            var observer = new TaskEventObserver();
            var schedulerThread = new SampleSchedulerThread();
            var scheduler = new DynamoScheduler(schedulerThread, false);
            scheduler.TaskStateChanged += observer.OnTaskStateChanged;

            // Start scheduling a bunch of tasks.
            var asyncTasks = new AsyncTask[]
            {
                new ErrorProneAsyncTask(scheduler, 7), 
                new InconsequentialAsyncTask(scheduler, 100),
                new PrioritizedAsyncTask(scheduler, 1),
                new PrioritizedAsyncTask(scheduler, 5),
                new ErrorProneAsyncTask(scheduler, 3), 
                new InconsequentialAsyncTask(scheduler, 500),
                new InconsequentialAsyncTask(scheduler, 300),
                new PrioritizedAsyncTask(scheduler, 3), 
                new ErrorProneAsyncTask(scheduler, 5), 
            };

            foreach (SampleAsyncTask asyncTask in asyncTasks)
                scheduler.ScheduleForExecution(asyncTask);

            schedulerThread.GetSchedulerToProcessTasks();

            // Drops all InconsequentialAsyncTask and leave behind one.
            // Kept all PrioritizedAsyncTask instances and sorted them.
            var expected = new List<string>
            {
                // Scheduling notifications...

                "Scheduled: ErrorProneAsyncTask: 7",
                "Scheduled: InconsequentialAsyncTask: 100",
                "Scheduled: PrioritizedAsyncTask: 1",
                "Scheduled: PrioritizedAsyncTask: 5",
                "Scheduled: ErrorProneAsyncTask: 3",
                "Scheduled: InconsequentialAsyncTask: 500",
                "Scheduled: InconsequentialAsyncTask: 300",
                "Scheduled: PrioritizedAsyncTask: 3",
                "Scheduled: ErrorProneAsyncTask: 5",

                // Task discarded notifications...

                "Discarded: InconsequentialAsyncTask: 100",
                "Discarded: InconsequentialAsyncTask: 300",

                // Execution of remaining tasks...

                "ExecutionStarting: ErrorProneAsyncTask: 7",
                "ExecutionFailed: ErrorProneAsyncTask: 7",
                "CompletionHandled: ErrorProneAsyncTask: 7",

                "ExecutionStarting: PrioritizedAsyncTask: 1",
                "ExecutionCompleted: PrioritizedAsyncTask: 1",
                "CompletionHandled: PrioritizedAsyncTask: 1",

                "ExecutionStarting: PrioritizedAsyncTask: 5",
                "ExecutionCompleted: PrioritizedAsyncTask: 5",
                "CompletionHandled: PrioritizedAsyncTask: 5",

                "ExecutionStarting: ErrorProneAsyncTask: 3",
                "ExecutionFailed: ErrorProneAsyncTask: 3",
                "CompletionHandled: ErrorProneAsyncTask: 3",

                "ExecutionStarting: PrioritizedAsyncTask: 3",
                "ExecutionCompleted: PrioritizedAsyncTask: 3",
                "CompletionHandled: PrioritizedAsyncTask: 3",

                "ExecutionStarting: ErrorProneAsyncTask: 5",
                "ExecutionFailed: ErrorProneAsyncTask: 5",
                "CompletionHandled: ErrorProneAsyncTask: 5",

                // Execution of InconsequentialAsyncTask last...

                "ExecutionStarting: InconsequentialAsyncTask: 500",
                "ExecutionCompleted: InconsequentialAsyncTask: 500",
                "CompletionHandled: InconsequentialAsyncTask: 500"
            };

            Assert.AreEqual(expected.Count, observer.Results.Count());

            int index = 0;
            foreach (var actual in observer.Results)
            {
                Assert.AreEqual(expected[index++], actual);
            }
        }
Example #27
0
        /// <summary>
        /// This callback method is invoked in the context of ISchedulerThread 
        /// when UpdateGraphAsyncTask is completed.
        /// </summary>
        /// <param name="task">The original UpdateGraphAsyncTask instance.</param>
        private void OnUpdateGraphCompleted(AsyncTask task)
        {
            var updateTask = (UpdateGraphAsyncTask)task;
            var messages = new Dictionary<Guid, string>();

            // Runtime warnings take precedence over build warnings.
            foreach (var warning in updateTask.RuntimeWarnings)
            {
                var message = string.Join("\n", warning.Value.Select(w => w.Message));
                messages.Add(warning.Key, message);
            }

            foreach (var warning in updateTask.BuildWarnings)
            {
                // If there is already runtime warnings for 
                // this node, then ignore the build warnings.
                if (messages.ContainsKey(warning.Key))
                    continue;

                var message = string.Join("\n", warning.Value.Select(w => w.Message));
                messages.Add(warning.Key, message);
            }

            var workspace = updateTask.TargetedWorkspace;
            foreach (var message in messages)
            {
                var guid = message.Key;
                var node = workspace.Nodes.FirstOrDefault(n => n.GUID == guid);
                if (node == null)
                    continue;

                node.Warning(message.Value); // Update node warning message.
            }

            // Notify listeners (optional) of completion.
            RunSettings.RunEnabled = true; // Re-enable 'Run' button.

            //set the node execution preview to false;
            OnSetNodeDeltaState(new DeltaComputeStateEventArgs(new List<Guid>(), graphExecuted));

            // This method is guaranteed to be called in the context of 
            // ISchedulerThread (for Revit's case, it is the idle thread).
            // Dispatch the failure message display for execution on UI thread.
            // 
            EvaluationCompletedEventArgs e = task.Exception == null || IsTestMode
                ? new EvaluationCompletedEventArgs(true)
                : new EvaluationCompletedEventArgs(true, task.Exception);

            EvaluationCount ++;

            OnEvaluationCompleted(e);

            if (EngineController.IsDisposed) return;

            EngineController.ReconcileTraceDataAndNotify();

            // Refresh values of nodes that took part in update.
            foreach (var modifiedNode in updateTask.ModifiedNodes)
            {
                modifiedNode.RequestValueUpdateAsync(scheduler, EngineController);
            }

            scheduler.Tasks.AllComplete(_ =>
            {
                OnRefreshCompleted(e);
            });
        }
Example #28
0
        private void OnRenderPackageAggregationCompleted(AsyncTask asyncTask)
        {
            var task = asyncTask as AggregateRenderPackageAsyncTask;
            var rps = new List<RenderPackage>();
            rps.AddRange(task.NormalRenderPackages.Cast<RenderPackage>());
            rps.AddRange(task.SelectedRenderPackages.Cast<RenderPackage>());

            Debug.WriteLine(string.Format("Render aggregation complete for {0}", task.NodeId));

            var e = new VisualizationEventArgs(rps, task.NodeId, -1);
            OnResultsReadyToVisualize(this, e);
        }
Example #29
0
 internal TaskStateChangedEventArgs(AsyncTask task, State state)
 {
     Task = task;
     CurrentState = state;
 }
Example #30
0
        private void OnNodeModelRenderPackagesReady(AsyncTask asyncTask)
        {
            // By design the following method is invoked on the context of 
            // ISchedulerThread, if access to any UI element is desired within
            // the method, dispatch those actions on UI dispatcher *inside* the
            // method, *do not* dispatch the following call here as derived 
            // handler may need it to remain on the ISchedulerThread's context.
            // 

            // Fire event to tell render targets to request their visuals
            OnRenderComplete();

            // Call overridden method on visualization manager to
            // process whatever internal logic there is around
            // drawing a visualization.
            HandleRenderPackagesReadyCore();
        }
Example #31
0
        private void OnRenderPackageAggregationCompleted(AsyncTask asyncTask)
        {
            var task = asyncTask as AggregateRenderPackageAsyncTask;

            var e = new VisualizationEventArgs(task.NormalRenderPackages, task.SelectedRenderPackages, task.NodeId);
            OnResultsReadyToVisualize(e);
        }
        protected override TaskMergeInstruction CanMergeWithCore(AsyncTask otherTask)
        {
            var theOtherTask = otherTask as AggregateRenderPackageAsyncTask;
            if (theOtherTask == null)
                return base.CanMergeWithCore(otherTask);

            if (NodeId != theOtherTask.NodeId)
                return TaskMergeInstruction.KeepBoth;

            //// Comparing to another AggregateRenderPackageAsyncTask, the one 
            //// that gets scheduled more recently stay, while the earlier one 
            //// gets dropped. If this task has a higher tick count, keep this.
            //// 
            if (ScheduledTime.TickCount > theOtherTask.ScheduledTime.TickCount)
                return TaskMergeInstruction.KeepThis;

            return TaskMergeInstruction.KeepOther; // Otherwise, keep the other.
        }