private void TraceItemAdded(object sender, TraceEventArgs e)
 {
     lstTrace.Invoke(new TraceChanged(AddToTrace), e.ExecutedAction.ToString());
     if (e.ExecutedAction.IsDeadlocked) {
         if (_visual != null && _chosenAction != null) {
             UpdateState();
         }
         lstCandidateActions.Invoke(new MethodInvoker(lstCandidateActions.Items.Clear));
         txtCandidateDescription.Invoke(new MethodInvoker(delegate() { txtCandidateDescription.Text = ""; }));
     }
 }
        /// <summary>
        /// Finds all candidate actions for execution, and selects one to
        /// execute using the SelectionActionToExecute delegate.
        /// </summary>
        /// <returns>
        /// true if the Scheduler should continue, false if it is
        /// deadlocked.
        /// </returns>
        private bool SelectAndExecuteAction()
        {
            List <CandidateAction> candidates = FindAllCandidateActions();

            if (candidates.Count == 0)
            {
                return(HandleNoCandidateActions());
            }

            CandidateAction chosen;

            chosen = SelectAction(candidates);

            TraceEventArgs traceArgs = new TraceEventArgs()
            {
                ExecutedAction = chosen
            };

            Debug("Chose action");
            _trace.Add(chosen.ToString());

            if (TraceItemAdded != null)
            {
                TraceItemAdded(this, traceArgs);
            }

            //Now let them sync with each other if this
            //is a synchronous actino
            if (chosen.IsSync)
            {
                chosen.Action1.Sync(chosen.Action2);
                chosen.Action2.Sync(chosen.Action1);
            }

            List <ProcessBase> wakeUp      = new List <ProcessBase>();
            List <Guid>        wakeUpGuids = new List <Guid>();

            //if (chosen.Process1 == null) {
            //    throw new Exception("IS NULL");
            //}
            chosen.Process1.ChosenAction = chosen.Action1;
            wakeUpGuids.Add(chosen.Process1.SetID);
            wakeUp.Add(chosen.Process1);
            if (!chosen.IsAsync)
            {
                chosen.Process2.ChosenAction = chosen.Action2;
                wakeUp.Add(chosen.Process2);
                wakeUpGuids.Add(chosen.Process2.SetID);
            }

            if (chosen.IsAsync)
            {
                Debug("Chose async action " + chosen + ", proc " + chosen.Process1 + ".");
            }
            else
            {
                Debug("Chose action " + chosen + ", procs " + chosen.Process1 + " and " + chosen.Process2);
            }

            Logger.TraceDebug(chosen);

            Debug("TRACE: " + "\n     " + String.Join("\n     ", _trace.ToArray()));
            foreach (ProcessBase p in _activeProcs)
            {
                if (!wakeUp.Contains(p) && wakeUpGuids.Contains(p.SetID))
                {
                    p.ChosenAction = null;
                    wakeUp.Add(p);
                }
            }

            //Finally, wake everyone up that needs to do something
            foreach (ProcessBase p in wakeUp)
            {
                Debug("Waking up " + p);
                p.Continue();
            }
            return(true);
        }
        /// <summary>
        /// Finds all candidate actions for execution, and selects one to
        /// execute using the SelectionActionToExecute delegate.
        /// </summary>
        /// <returns>
        /// true if the Scheduler should continue, false if it is
        /// deadlocked.
        /// </returns>
        private bool SelectAndExecuteAction()
        {
            List<CandidateAction> candidates = FindAllCandidateActions();

            if (candidates.Count == 0) {
                return HandleNoCandidateActions();
            }

            CandidateAction chosen;
            chosen = SelectAction(candidates);

            TraceEventArgs traceArgs = new TraceEventArgs() { ExecutedAction = chosen };

            Debug("Chose action");
            _trace.Add(chosen.ToString());

            if (TraceItemAdded != null) {
                TraceItemAdded(this, traceArgs);
            }

            //Now let them sync with each other if this
            //is a synchronous actino
            if (chosen.IsSync) {
                chosen.Action1.Sync(chosen.Action2);
                chosen.Action2.Sync(chosen.Action1);
            }

            List<ProcessBase> wakeUp = new List<ProcessBase>();
            List<Guid> wakeUpGuids = new List<Guid>();

            //if (chosen.Process1 == null) {
            //    throw new Exception("IS NULL");
            //}
            chosen.Process1.ChosenAction = chosen.Action1;
            wakeUpGuids.Add(chosen.Process1.SetID);
            wakeUp.Add(chosen.Process1);
            if (!chosen.IsAsync) {
                chosen.Process2.ChosenAction = chosen.Action2;
                wakeUp.Add(chosen.Process2);
                wakeUpGuids.Add(chosen.Process2.SetID);
            }

            if (chosen.IsAsync) {
                Debug("Chose async action " + chosen + ", proc " + chosen.Process1 + ".");
            } else {
                Debug("Chose action " + chosen + ", procs " + chosen.Process1 + " and " + chosen.Process2);
            }

            Logger.TraceDebug(chosen);

            Debug("TRACE: " + "\n     " + String.Join("\n     ", _trace.ToArray()));
            foreach (ProcessBase p in _activeProcs) {
                if (!wakeUp.Contains(p) && wakeUpGuids.Contains(p.SetID)) {
                    p.ChosenAction = null;
                    wakeUp.Add(p);
                }
            }

            //Finally, wake everyone up that needs to do something
            foreach (ProcessBase p in wakeUp) {
                Debug("Waking up " + p);
                p.Continue();
            }
            return true;
        }