static void Main() { // Create the WorkflowRuntime WorkflowRuntime workflowRuntime = new WorkflowRuntime(); Console.WriteLine("App.Main thread:{0}", Thread.CurrentThread.ManagedThreadId); workflowRuntime.StartRuntime(); Type type = typeof(SequentialWorkflow); // Listen for the workflow events workflowRuntime.WorkflowCompleted += OnWorkflowCompleted; workflowRuntime.WorkflowTerminated += OnWorkflowTerminated; WorkflowInstance wi = workflowRuntime.CreateWorkflow(type); wi.Start(); Console.WriteLine("Enquing data"); wi.EnqueueItem("LaNostra_Queue", "Hello", null, null); waitHandle.WaitOne(); // Stop the runtime Console.WriteLine("Program Complete."); //workflowRuntime.Dispose (); }
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); } } }
Guid Enqueue(Guid callee, ChildData cd, object prms) { Guid caller = cd.Parent; WorkflowInstance c = this.Runtime.GetWorkflow(caller); IComparable qn = cd.QueueName; c.EnqueueItem(qn, prms, null, null); _childWorkflows.Remove(callee); return(caller); }
/// <summary> /// Runs the workflow. /// </summary> /// <param name="entity">The entity.</param> /// <param name="executionResult">The execution result.</param> private static void RunWorkflow(AssignmentEntity entity) { Guid wfInstanceId = (Guid)entity.WorkflowInstanceId; string queueName = entity.WorkflowActivityName; WorkflowInstance instance = GlobalWorkflowRuntime.WorkflowRuntime.GetWorkflow(wfInstanceId); instance.EnqueueItem(queueName, entity, null, null); GlobalWorkflowRuntime.RunWorkflow(instance); }
public void DeliverMessage(ExternalDataEventArgs eventArgs, IComparable queueName, object message, object workItem, IPendingWork workHandler) { WorkflowInstance workflow = this.eds.Runtime.GetWorkflow(eventArgs.InstanceId); if (eventArgs.WaitForIdle) { workflow.EnqueueItemOnIdle(queueName, message, workHandler, workItem); } else { workflow.EnqueueItem(queueName, message, workHandler, workItem); } }
private static void SafeEnqueueItem(WorkflowInstance instance, EventQueueName key, MethodMessage message) { Label_0000: try { instance.EnqueueItem(key, message, null, null); } catch (WorkflowOwnershipException) { WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Warning, 0, string.Format(CultureInfo.InvariantCulture, "Workflow Web Host Encountered Workflow Instance Ownership conflict for instanceid {0}.", new object[] { instance.InstanceId })); Thread.Sleep(500); goto Label_0000; } }
private void DeliverToWorkflow(FileWatcherSubscription subscription, FileSystemEventArgs fileSystemEventArgs) { try { // We can't just use the FileSystemEventArgs because it's not serializable FileWatcherEventArgs eventArgs = new FileWatcherEventArgs(fileSystemEventArgs); WorkflowInstance workflowInstance = this.runtime.GetWorkflow(subscription.WorkflowInstanceId); workflowInstance.EnqueueItem(subscription.QueueName, eventArgs, null, null); } catch (Exception e) { // Write the exception out to the Debug console and throw the exception System.Diagnostics.Debug.WriteLine(e); throw e; } }
//Back - off logic for conflicting workflow load across workflow runtime boundaries. static void SafeEnqueueItem(WorkflowInstance instance, EventQueueName key, MethodMessage message) { while (true) //When Execution times out ASP.NET going to forcefully plung this request. { try { instance.EnqueueItem(key, message, null, null); return; } catch (WorkflowOwnershipException) { WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Warning, 0, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Workflow Web Host Encountered Workflow Instance Ownership conflict for instanceid {0}.", instance.InstanceId)); //Back-off for 1/2 sec. Should we make this configurable? System.Threading.Thread.Sleep(500); continue; } } }
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); } }
protected override void OnStarted() { base.OnStarted(); if (null == _CompletedHandler) { _CompletedHandler = delegate(object o, WorkflowCompletedEventArgs e) { var instanceId = e.WorkflowInstance.InstanceId; if (_WorkflowQueue.ContainsKey(instanceId)) { WorkflowInfo wf = _WorkflowQueue[instanceId]; WorkflowInstance c = this.Runtime.GetWorkflow(wf.Caller); c.EnqueueItem(wf.qn, e.OutputParameters, null, null); _WorkflowQueue.Remove(instanceId); } }; this.Runtime.WorkflowCompleted += _CompletedHandler; } if (null == _TerminatedHandler) { _TerminatedHandler = delegate(object o, WorkflowTerminatedEventArgs e) { var instanceId = e.WorkflowInstance.InstanceId; if (_WorkflowQueue.ContainsKey(instanceId)) { WorkflowInfo wf = _WorkflowQueue[instanceId]; WorkflowInstance c = this.Runtime.GetWorkflow(wf.Caller); c.EnqueueItem(wf.qn, new Exception("Called Workflow Terminated", e.Exception), null, null); _WorkflowQueue.Remove(instanceId); } }; this.Runtime.WorkflowTerminated += _TerminatedHandler; } }
static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage WorkflowThreading.exe [Single | Multi] [Delay | WaitForMessage]"); return; } if (!args[0].Equals("Single", StringComparison.OrdinalIgnoreCase) && !args[0].Equals("Multi", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("Specify Single or Multi as a first command line parameter"); return; } if (!args[1].Equals("Delay", StringComparison.OrdinalIgnoreCase) && !args[1].Equals("WaitForMessage", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("Specify Delay or WaitForMessage as a second command line parameter"); return; } ThreadMonitor.Enlist(Thread.CurrentThread, "Host"); Console.ForegroundColor = ConsoleColor.White; // Start the engine using (workflowRuntime = new WorkflowRuntime()) { ManualWorkflowSchedulerService scheduler = null; if (args[0].ToString().Equals("Single", StringComparison.OrdinalIgnoreCase)) { scheduler = new ManualWorkflowSchedulerService(); workflowRuntime.AddService(scheduler); } workflowRuntime.StartRuntime(); // Set up the workflow runtime event handlers workflowRuntime.WorkflowCompleted += OnWorkflowCompleted; workflowRuntime.WorkflowTerminated += OnWorkflowTerminated; workflowRuntime.WorkflowIdled += OnWorkflowIdled; workflowRuntime.WorkflowCreated += OnWorkflowCreated; // Load the workflow type Type type = typeof(ThreadingWorkflow); Dictionary <string, object> workflowParameters = new Dictionary <string, object>(); workflowParameters.Add("BranchFlag", args[1]); Console.WriteLine("\n--- Before Starting Workflow ---\n"); // Create an instance of the workflow workflowInstance = workflowRuntime.CreateWorkflow(type, workflowParameters); workflowInstance.Start(); Console.WriteLine("\n--- After Starting Workflow ---\n"); if (scheduler != null) { scheduler.RunWorkflow(workflowInstance.InstanceId); } readyHandle.WaitOne(); if (args[1].Equals("WaitForMessage", StringComparison.OrdinalIgnoreCase)) { // Send message to WaitForMessageActivity's queue workflowInstance.EnqueueItem("WaitForMessageActivityQueue", "Hello", null, null); } if (scheduler != null) { scheduler.RunWorkflow(workflowInstance.InstanceId); } waitHandle.WaitOne(); workflowRuntime.StopRuntime(); } }
//<snippet219> static void Submit(WorkflowInstance instance, string input) { instance.EnqueueItem("Queue", input, null, null); }