static void OnWorkflowIdled(object sender, WorkflowEventArgs e) { WorkflowInstance workflow = e.WorkflowInstance; Console.WriteLine("\n...waiting for 3 seconds... \n"); Thread.Sleep(3000); // what activity is blocking the workflow ReadOnlyCollection <WorkflowQueueInfo> wqi = workflow.GetWorkflowQueueData(); foreach (WorkflowQueueInfo q in wqi) { EventQueueName eq = q.QueueName as EventQueueName; if (eq != null) { // get activity that is waiting for event ReadOnlyCollection <string> blockedActivity = q.SubscribedActivityNames; Console.WriteLine("Host: Workflow is blocked on " + blockedActivity[0]); // this event is never going to arrive eg. employee left the company // lets send an exception to this queue // it will either be handled by exception handler that was modeled in workflow // or the runtime will unwind running compensation handlers and exit the workflow Console.WriteLine("Host: This event is not going to arrive"); Console.WriteLine("Host: Cancel workflow with unhandled exception"); workflow.EnqueueItem(q.QueueName, new Exception("ExitWorkflowException"), null, null); } } }
protected override void Initialize(IServiceProvider provider) { if (provider == null) { throw new ArgumentNullException("provider"); } if (this.Parent != null) { throw new InvalidOperationException("This is a root Activity"); } _queueName = new EventQueueName(this.Type, this.MethodName); WorkflowQueuingService queueService = (WorkflowQueuingService)provider.GetService(typeof(WorkflowQueuingService)); if (queueService != null) { WorkflowQueue queue = null; if (queueService.Exists(_queueName)) { queue = queueService.GetWorkflowQueue(_queueName); queue.Enabled = true; } else { queue = queueService.CreateWorkflowQueue(_queueName, true); } } base.Initialize(provider); }
static public WorkflowAction[] GetSubscribedActions(Guid workflowId) { List <WorkflowAction> actions = new List <WorkflowAction>(); SqlTrackingQuery sqlTrackingQuery = new SqlTrackingQuery(ConfigurationManager.ConnectionStrings[Constants.Database.TenantWorkflowStore].ConnectionString); SqlTrackingWorkflowInstance trackingWorkflow; if (!sqlTrackingQuery.TryGetWorkflow(workflowId, out trackingWorkflow) || trackingWorkflow.Status == WorkflowStatus.Completed || trackingWorkflow.Status == WorkflowStatus.Terminated) { return(actions.ToArray()); } WorkflowInstance instance = Runtime.GetWorkflow(workflowId); Activity workflow = instance.GetWorkflowDefinition(); ReadOnlyCollection <WorkflowQueueInfo> queues = instance.GetWorkflowQueueData(); foreach (WorkflowQueueInfo s in queues) { if (s.SubscribedActivityNames.Count == 0) { continue; } EventQueueName eventQueueName = s.QueueName as EventQueueName; if (eventQueueName != null) { WorkflowAction action = new WorkflowAction(); action.ActionName = eventQueueName.MethodName; string activityName = s.SubscribedActivityNames[0]; string[] splittedNames = activityName.Split('.'); action.StepName = splittedNames[0]; HandleExternalEventActivity activity = workflow.GetActivityByName(activityName) as HandleExternalEventActivity; if (activity != null && activity.Roles != null && activity.Roles.Count > 0) { List <string> roleNames = new List <string>(); foreach (WorkflowRole role in activity.Roles) { roleNames.Add(role.Name); } action.QualifiedRoles = roleNames.ToArray(); } actions.Add(action); } } return(actions.ToArray()); }
/// <summary> /// Handle the WorkflowIdled event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void WorkflowRuntime_WorkflowIdled( object sender, WorkflowEventArgs e) { UpdateDelegate theDelegate = delegate() { //first disable all buttons EnableEventButtons(false); //determine which events are allowed. //Note: ReadOnlyCollection is in the //System.Collections.ObjectModel namespace. ReadOnlyCollection <WorkflowQueueInfo> queueInfoData = _instanceWrapper.WorkflowInstance.GetWorkflowQueueData(); if (queueInfoData != null) { foreach (WorkflowQueueInfo info in queueInfoData) { EventQueueName eventQueue = info.QueueName as EventQueueName; if (eventQueue == null) { break; } //enable the button that is associated //with this event EnableButtonForEvent(eventQueue.MethodName); } } #if STATEMACHINEINSTANCE StateMachineWorkflowInstance stateMachine = new StateMachineWorkflowInstance( _workflowManager.WorkflowRuntime, _instanceWrapper.WorkflowInstance.InstanceId); //set the form title to the current state name this.Text = String.Format( "State: {0}", stateMachine.CurrentStateName); #endif }; //execute the anonymous delegate on the UI thread this.Invoke(theDelegate); }
public void SendMessage(IMethodMessage message) { // identity string identity = WorkflowInvoker.Identity(); if (!string.IsNullOrEmpty(identity) && message.LogicalCallContext != null) { // workaround to create an IdentityContextData for LogicalCallContext Type type = Type.GetType("System.Workflow.Activities.IdentityContextData, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); object identityContextData = Activator.CreateInstance(type, BindingFlags.CreateInstance | BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new object[] { identity }, CultureInfo.CurrentCulture); message.LogicalCallContext.SetData("__identitycontext__", identityContextData); } // contract type Type contractType = Type.GetType(message.TypeName); if (contractType == null) { throw new TypeLoadException(message.TypeName); } // create queue name EventQueueName qn = new EventQueueName(contractType, message.MethodName); // enqueue item if (_bStateMachine) { if (_localservice.Scheduler != null) { _localservice.Scheduler.RunWorkflow(_instance.InstanceId); } _instance.EnqueueItemOnIdle(qn, message, null, null); } else { _instance.EnqueueItem(qn, message, null, null); } if (_localservice.Scheduler != null) { _localservice.Scheduler.RunWorkflow(_instance.InstanceId); } }
private void EnableButtons() { // If the State is not set, then don't enable any buttons if (stateMachineInstance.CurrentState == null) { return; } // Enable the buttons on this form, based on the Messages (events) // ...allowed into the State Machine workflow, based on it's current state ReadOnlyCollection <WorkflowQueueInfo> queues = stateMachineInstance.WorkflowInstance.GetWorkflowQueueData(); Collection <string> MessagesAllowed = new Collection <string>(); foreach (WorkflowQueueInfo s in queues) { EventQueueName eventQueueName = s.QueueName as EventQueueName; if (eventQueueName != null) { MessagesAllowed.Add(eventQueueName.MethodName); } } if (MessagesAllowed.Contains("Button0Pressed")) { this.button0.Enabled = true; } if (MessagesAllowed.Contains("Button1Pressed")) { this.button1.Enabled = true; } if (MessagesAllowed.Contains("Button2Pressed")) { this.button2.Enabled = true; } if (MessagesAllowed.Contains("Button3Pressed")) { this.button3.Enabled = true; } if (MessagesAllowed.Contains("Button4Pressed")) { this.button4.Enabled = true; } if (MessagesAllowed.Contains("Button5Pressed")) { this.button5.Enabled = true; } if (MessagesAllowed.Contains("Button6Pressed")) { this.button6.Enabled = true; } if (MessagesAllowed.Contains("Button7Pressed")) { this.button7.Enabled = true; } if (MessagesAllowed.Contains("Button8Pressed")) { this.button8.Enabled = true; } if (MessagesAllowed.Contains("Button9Pressed")) { this.button9.Enabled = true; } if (MessagesAllowed.Contains("ButtonStarPressed")) { this.buttonstar.Enabled = true; } if (MessagesAllowed.Contains("ButtonPoundPressed")) { this.buttonpound.Enabled = true; } }
private void EnableUI() { // Make sure an item in the ListView is selected if (this.listViewOrders.SelectedItems.Count == 0) { return; } // If the workflow is Completed or Terminated, then don't enable any buttons string workflowStatus = this.listViewOrders.SelectedItems[0].SubItems[WorkflowStatusColumnIndex].Text; if ((workflowStatus.Equals("Completed")) || (workflowStatus.Equals("Terminated"))) { return; } // Return the StateMachineInstance object StateMachineWorkflowInstance stateMachineInstance = this.GetSelectedStateMachineInstance(); // If the State is not set, then don't enable any buttons if (stateMachineInstance == null || stateMachineInstance.CurrentState == null) { return; } // Enable the buttons on this form, based on the Messages (events) // ...allowed into the State Machine workflow, based on its current state ReadOnlyCollection <WorkflowQueueInfo> subActivities = stateMachineInstance.WorkflowInstance.GetWorkflowQueueData(); Collection <string> MessagesAllowed = new Collection <string>(); foreach (WorkflowQueueInfo queueInfo in subActivities) { // Cast the Queue Name to the class Event Queue Name to get the event name string EventQueueName queuename = queueInfo.QueueName as EventQueueName; if (queuename != null) { MessagesAllowed.Add(queuename.MethodName); } } if (MessagesAllowed.Contains("OrderCanceled")) { this.buttonOrderCanceled.Enabled = true; } if (MessagesAllowed.Contains("OrderProcessed")) { this.buttonOrderProcessed.Enabled = true; } if (MessagesAllowed.Contains("OrderShipped")) { this.buttonOrderShipped.Enabled = true; } if (MessagesAllowed.Contains("OrderUpdated")) { this.buttonOrderUpdated.Enabled = true; } // Load the list of available states into the SetState combo box and enable it this.comboBoxWorkflowStates.Enabled = true; this.buttonSetState.Enabled = true; this.PopulateSetStateComboBox(); this.addOnHoldStateToolStripMenuItem.Enabled = true; }