/// <summary> /// 克隆一个实例 /// </summary> /// <param name="WfRuntimeClone"></param> /// <param name="instanceClone"></param> /// <param name="WfRuntime"></param> /// <returns></returns> public static WorkflowInstance CloneWorkflowInstance(WorkflowRuntime WfRuntimeClone, WorkflowInstance instanceClone, WorkflowRuntime WfRuntime) { try { if (!WfRuntimeClone.IsStarted) { WfRuntimeClone.StartRuntime(); } StateMachineWorkflowInstance workflowinstance = new StateMachineWorkflowInstance(WfRuntimeClone, instanceClone.InstanceId); System.Workflow.Activities.StateMachineWorkflowActivity smworkflow = new StateMachineWorkflowActivity(); smworkflow = workflowinstance.StateMachineWorkflow; RuleDefinitions ruleDefinitions = smworkflow.GetValue(RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions; WorkflowMarkupSerializer markupSerializer = new WorkflowMarkupSerializer(); StringBuilder xoml = new StringBuilder(); StringBuilder rule = new StringBuilder(); XmlWriter xmlWriter = XmlWriter.Create(xoml); XmlWriter ruleWriter = XmlWriter.Create(rule); markupSerializer.Serialize(xmlWriter, smworkflow); if (ruleDefinitions != null) { markupSerializer.Serialize(ruleWriter, ruleDefinitions); } xmlWriter.Close(); ruleWriter.Close(); StringReader readxoml = new StringReader(xoml.ToString()); XmlReader readerxoml = XmlReader.Create(readxoml); WorkflowInstance instance; if (ruleDefinitions == null) { instance = WfRuntime.CreateWorkflow(readerxoml); } else { StringReader readrule = new StringReader(rule.ToString()); XmlReader readerrule = XmlReader.Create(readrule); instance = WfRuntime.CreateWorkflow(readerxoml, readerrule, null); } instance.Start(); return(instance); } catch (Exception ex) { LogHelper.WriteLog("CloneWorkflowInstance异常信息 :" + ex.ToString()); throw new Exception(ex.Message); } }
void ShowHardCauda(object activity) { if (activity is StateMachineWorkflowActivity) { StateMachineWorkflowActivity sa = activity as StateMachineWorkflowActivity; var v1 = ElementList.Single(p => p.Name == sa.InitialStateName); v1.类型 = "头"; var v2 = ElementList.Single(p => p.Name == sa.CompletedStateName); v2.类型 = "尾"; var v3 = ElementList.Single(p => p.Name == "归档状态"); v3.类型 = "归档"; } }
public static DataTable GetChildActivityList(WorkflowDescription wfDescription, object activity) { DataTable dt = new DataTable(); dt.Locale = CultureInfo.InvariantCulture; dt.Columns.Add("Id", typeof(string)); dt.Columns.Add("Number", typeof(int)); dt.Columns.Add("Subject", typeof(string)); dt.Columns.Add("User", typeof(int)); dt.Columns.Add("DueDate", typeof(DateTime)); dt.Columns.Add("State", typeof(ActivityStatus)); dt.Columns.Add("IsBlock", typeof(bool)); dt.Columns.Add("ReadOnlyLibraryAccess", typeof(bool)); if (activity is SequentialWorkflowActivity) { SequentialWorkflowActivity block = (SequentialWorkflowActivity)activity; foreach (Activity child in block.Activities) { ProcessChildActivity(wfDescription, child, dt); } } else if (activity is StateMachineWorkflowActivity) { StateMachineWorkflowActivity block = (StateMachineWorkflowActivity)activity; foreach (Activity child in block.Activities) { ProcessChildActivity(wfDescription, child, dt); } } else if (activity is BlockActivity) { BlockActivity block = (BlockActivity)activity; foreach (Activity child in block.Activities) { ProcessChildActivity(wfDescription, child, dt); } } return(dt); }
private static void ProcessActivity(WorkflowDescription wfDescription, Activity activity, DataTable dt, int level) { DataRow row = dt.NewRow(); row["Id"] = activity.QualifiedName; row["Number"] = dt.Rows.Count + 1; if (activity is SequentialWorkflowActivity) { row["Subject"] = wfDescription.Name; row["IsBlock"] = true; } else if (activity is StateMachineWorkflowActivity) { row["Subject"] = wfDescription.Name; row["IsBlock"] = true; } else if (activity is BlockActivity) { if (((BlockActivity)activity).Type == BlockActivityType.All) { row["Subject"] = "{IbnFramework.BusinessProcess:BlockActivityTypeAll}"; } else { row["Subject"] = "{IbnFramework.BusinessProcess:BlockActivityTypeAny}"; } row["IsBlock"] = true; } else if (activity is CreateAssignmentAndWaitResultActivity) { PropertyValueCollection properties = ((CreateAssignmentAndWaitResultActivity)activity).AssignmentProperties; row["Subject"] = properties[AssignmentEntity.FieldSubject].ToString(); row["User"] = (int)properties[AssignmentEntity.FieldUserId]; if (properties[AssignmentEntity.FieldPlanFinishDate] != null) { row["DueDate"] = (DateTime)properties[AssignmentEntity.FieldPlanFinishDate]; } row["IsBlock"] = false; } if (row["Subject"] == DBNull.Value) { row["Subject"] = "{IbnFramework.BusinessProcess:NoSubject}"; } row["State"] = GetActivityStatus(wfDescription, activity); row["Level"] = level; dt.Rows.Add(row); level++; if (activity is SequentialWorkflowActivity) { SequentialWorkflowActivity block = (SequentialWorkflowActivity)activity; foreach (Activity child in block.Activities) { ProcessActivity(wfDescription, child, dt, level); } } else if (activity is StateMachineWorkflowActivity) { StateMachineWorkflowActivity block = (StateMachineWorkflowActivity)activity; foreach (Activity child in block.Activities) { ProcessActivity(wfDescription, child, dt, level); } } else if (activity is BlockActivity) { BlockActivity block = (BlockActivity)activity; foreach (Activity child in block.Activities) { ProcessActivity(wfDescription, child, dt, level); } } }
// Workflow processor internal static void RunWorkflow(Object stateInfo) { Stack <Activity> stack = new Stack <Activity> (); WorkflowInstance wi = WorkflowRuntime.GetInstanceFromGuid((Guid)stateInfo); wi.timer_subscriptions = new Timer(TimerSubscriptionsCallback, wi, 0, 1000); Activity activity = wi.GetWorkflowDefinition(); Activity next_activity; ActivityExecutionContextManager manager = new ActivityExecutionContextManager(wi); ActivityExecutionContext context; List <DelayActivity> waiting = new List <DelayActivity> (); bool wait = false; StateMachineWorkflowActivity state_machine = null; #if DEBUG_EXECUTIONLOOP Console.WriteLine("Initiating thread for activity {0}", wi.GetWorkflowDefinition()); #endif context = manager.CreateExecutionContext(activity); // Main Workflow execution loop while (activity != null) { next_activity = null; if (activity.NeedsExecution) { #if DEBUG_EXECUTIONLOOP Console.WriteLine("*** Executing {0}, parallel {1}", activity, activity.ParallelParent); #endif context.ExecuteActivity(activity); } // If this a state machine changing its statge update StateMachineWorkflowActivity if (state_machine != null && IsBasedOnType(activity, typeof(SetStateActivity))) { state_machine.SetCurrentStateName(((SetStateActivity)activity).TargetStateName); } #if DEBUG_EXECUTIONLOOP Console.WriteLine(" ActivitiesToExecute.Count {0}, stack {1}, waiting {2}", activity.ActivitiesToExecute.Count, stack.Count, waiting.Count); #endif wait = false; // State machine workflow, first activity is InitialStateName if (IsBasedOnType(activity, typeof(StateMachineWorkflowActivity))) { state_machine = (StateMachineWorkflowActivity)activity; stack.Push(activity.GetActivityByName(state_machine.InitialStateName)); state_machine.SetCurrentStateName(state_machine.InitialStateName); #if DEBUG_EXECUTIONLOOP Console.WriteLine(" StateMachineWorkflowActivity, pushing {0}", activity.GetActivityByName(sm.InitialStateName)); #endif } // TODO: if (IsBasedOnType (current, typeof (CompositeActivity))) { if (activity.GetType() == typeof(DelayActivity)) { if (activity.ParallelParent == null) { wi.WorkflowRuntime.OnWorkflowIdled(wi); waiting.Add((DelayActivity)activity); wait = true; } else { // Continue from parent activities // TODO: This can be moved to the Execute method // of the paralell activity if (activity.ParallelParent.ActivitiesToExecute.Count > 0) { stack.Push(activity.ParallelParent); #if DEBUG_EXECUTIONLOOP Console.WriteLine("Pushing parent {0}", activity.ParallelParent); #endif waiting.Add((DelayActivity)activity); } else // If not possible, wait for the delay { #if DEBUG_EXECUTIONLOOP Console.WriteLine("Schedule Waiting"); #endif waiting.Add((DelayActivity)activity); wait = true; } } } if (activity.NeedsExecution) // ex. While { stack.Push(activity); } if (activity.ActivitiesToExecute.Count == 0 && stack.Count == 0 && waiting.Count == 0) { #if DEBUG_EXECUTIONLOOP Console.WriteLine("Exiting..."); #endif break; } // Does it have sub-activities to run? // Delay is not composite, cannot have children activities if (wait == false) { if (activity.ActivitiesToExecute.Count > 0) { next_activity = activity.ActivitiesToExecute.Dequeue(); #if DEBUG_EXECUTIONLOOP Console.WriteLine("Next Activity A {0}", next_activity); #endif if (activity.ActivitiesToExecute.Count > 0) { stack.Push(activity); } } else { if (stack.Count > 0) { next_activity = stack.Pop(); } if (next_activity != null && next_activity.NeedsExecution == false) { if (next_activity.ActivitiesToExecute.Count > 0) { next_activity = next_activity.ActivitiesToExecute.Dequeue(); } } #if DEBUG_EXECUTIONLOOP Console.WriteLine("Next Activity B {0}", next_activity); #endif } } if (next_activity == null) { if (waiting.Count > 0) { #if DEBUG_EXECUTIONLOOP Console.WriteLine("Waiting for {0} handles...", waiting.Count); #endif wi.WorkflowRuntime.OnWorkflowIdled(wi); DelayActivity.WaitEvent.WaitOne(); } } // Do we have delay activities no longer waiting? foreach (DelayActivity delay in waiting) { if (delay.Delayed == false) { bool flag = false; // Continue with the list of activities pending in the parent next_activity = delay.Parent; waiting.Remove(delay); #if DEBUG_EXECUTIONLOOP Console.WriteLine("Delayed Parent {0}", next_activity); #endif if (next_activity.ActivitiesToExecute.Count > 0) { if (next_activity.ActivitiesToExecute.Count > 1) { flag = true; } if (next_activity != null) { next_activity = next_activity.ActivitiesToExecute.Dequeue(); if (flag == true) { stack.Push(delay.Parent); } } } break; } } #if DEBUG_EXECUTIONLOOP Console.WriteLine("Next activity to process {0}", next_activity); #endif activity = next_activity; } wi.WorkflowRuntime.OnWorkflowCompleted(wi); }