public void ScheduleItem(SchedulableItem s, bool isInAtomicTransaction, bool transacted) { lock (this.syncObject) { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 1, "Workflow Runtime: Scheduler: InstanceId: {0} : Scheduling entry: {1}", this.RootWorkflowExecutor.InstanceIdString, s.ToString()); // SchedulableItems in AtomicTransaction has higher priority Queue <SchedulableItem> q = isInAtomicTransaction ? this.highPriorityEntriesQueue : this.normalPriorityEntriesQueue; q.Enqueue(s); if (transacted) { if (transactedEntries == null) { transactedEntries = new Queue <SchedulableItem>(); } transactedEntries.Enqueue(s); } if (!this.threadRequested) { if (this.CanRun) { this.RootWorkflowExecutor.ScheduleForWork(); this.threadRequested = true; } } this.empty = false; } }
void AddItemToBeScheduledLater(Activity atomicActivity, SchedulableItem item) { if (atomicActivity == null) { return; } // Activity may not be atomic and is an activity which is not // yet scheduled for execution (typically receive case) if (!atomicActivity.SupportsTransaction) { return; } TransactionalProperties transactionalProperties = (TransactionalProperties)atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty); if (transactionalProperties != null) { lock (transactionalProperties) { List <SchedulableItem> notifications = null; notifications = transactionalProperties.ItemsToBeScheduledAtCompletion; if (notifications == null) { notifications = new List <SchedulableItem>(); transactionalProperties.ItemsToBeScheduledAtCompletion = notifications; } notifications.Add(item); } } }
private SchedulableItem GetItemToRun() { SchedulableItem ret = null; lock (this.syncObject) { bool workToDo = false; if ((this.highPriorityEntriesQueue.Count > 0) || (this.normalPriorityEntriesQueue.Count > 0)) { workToDo = true; // If an abort or termination of the workflow has been requested, // then the workflow should try to terminate ASAP. Even transaction scopes // in progress shouldn't be executed to completion. (Ref: 16534) if (this.AbortOrTerminateRequested) { ret = null; } // got work to do in the scheduler else if ((this.highPriorityEntriesQueue.Count > 0)) { ret = this.highPriorityEntriesQueue.Dequeue(); } else if (this.CanRun) { // the scheduler can run right now // // pick an entry to run // if (((IWorkflowCoreRuntime)this.RootWorkflowExecutor).CurrentAtomicActivity == null && (this.normalPriorityEntriesQueue.Count > 0)) { ret = this.normalPriorityEntriesQueue.Dequeue(); } } else { // scheduler can't run right now.. even though there is ready work // do nothing in the scheduler ret = null; } } if (!workToDo) { // no ready work to do in the scheduler... // we are gonna return the thread back this.empty = true; } // set it to true only iff there is something to run this.threadRequested = (ret != null); } return(ret); }
public void ScheduleItem(SchedulableItem item, bool isInAtomicTransaction, bool transacted, bool queueInTransaction) { if (queueInTransaction) { this.AddItemToBeScheduledLater(this.CurrentActivity, item); } else { this.scheduler.ScheduleItem(item, isInAtomicTransaction); } }
private SchedulableItem GetItemToRun() { SchedulableItem item = null; lock (this.syncObject) { bool flag = false; if ((this.highPriorityEntriesQueue.Count > 0) || (this.normalPriorityEntriesQueue.Count > 0)) { flag = true; if (this.AbortOrTerminateRequested) { item = null; } else if (this.highPriorityEntriesQueue.Count > 0) { item = this.highPriorityEntriesQueue.Dequeue(); } else if (this.CanRun) { if ((((IWorkflowCoreRuntime)this.RootWorkflowExecutor).CurrentAtomicActivity == null) && (this.normalPriorityEntriesQueue.Count > 0)) { item = this.normalPriorityEntriesQueue.Dequeue(); } } else { item = null; } } if (!flag) { this.empty = true; } this.threadRequested = item != null; } return(item); }
public void ScheduleItem(SchedulableItem item, bool isInAtomicTransaction) { (isInAtomicTransaction ? this.atomicActivityQueue : this.schedulerQueue).Enqueue(item); }
private void AddItemToBeScheduledLater(System.Workflow.ComponentModel.Activity atomicActivity, SchedulableItem item) { if ((atomicActivity != null) && atomicActivity.SupportsTransaction) { TransactionalProperties properties = (TransactionalProperties)atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty); if (properties != null) { lock (properties) { List <SchedulableItem> itemsToBeScheduledAtCompletion = null; itemsToBeScheduledAtCompletion = properties.ItemsToBeScheduledAtCompletion; if (itemsToBeScheduledAtCompletion == null) { itemsToBeScheduledAtCompletion = new List <SchedulableItem>(); properties.ItemsToBeScheduledAtCompletion = itemsToBeScheduledAtCompletion; } itemsToBeScheduledAtCompletion.Add(item); } } } }
public void Run() { do { this.RootWorkflowExecutor.ProcessQueuedEvents(); // Get item to run SchedulableItem item = GetItemToRun(); bool runningItem = false; // no ready work to run... go away if (item == null) { break; } Activity itemActivity = null; Exception exp = null; TransactionalProperties transactionalProperties = null; int contextId = item.ContextId; // This function gets the root or enclosing while-loop activity Activity contextActivity = this.RootWorkflowExecutor.GetContextActivityForId(contextId); if (contextActivity == null) { throw new InvalidOperationException(ExecutionStringManager.InvalidExecutionContext); } // This is the activity corresponding to the item's ActivityId itemActivity = contextActivity.GetActivityByName(item.ActivityId); using (new ServiceEnvironment(itemActivity)) { exp = null; bool ignoreFinallyBlock = false; try { // item preamble // set up the item transactional context if necessary // Debug.Assert(itemActivity != null, "null itemActivity"); if (itemActivity == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidActivityName, item.ActivityId)); } Activity atomicActivity = null; if (this.RootWorkflowExecutor.IsActivityInAtomicContext(itemActivity, out atomicActivity)) { transactionalProperties = (TransactionalProperties)atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty); // If we've aborted for any reason stop now! // If we attempt to enter a new TransactionScope the com+ context will get corrupted // See windows se bug 137267 if (!WorkflowExecutor.CheckAndProcessTransactionAborted(transactionalProperties)) { if (transactionalProperties.TransactionScope == null) { // Use TimeSpan.Zero so scope will not create timeout independent of the transaction // Use EnterpriseServicesInteropOption.Full to flow transaction to COM+ transactionalProperties.TransactionScope = new TransactionScope(transactionalProperties.Transaction, TimeSpan.Zero, EnterpriseServicesInteropOption.Full); WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: Scheduler: instanceId: " + this.RootWorkflowExecutor.InstanceIdString + "Entered into TransactionScope, Current atomic acitivity " + atomicActivity.Name); } } } // Run the item // runningItem = true; WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 1, "Workflow Runtime: Scheduler: InstanceId: {0} : Running scheduled entry: {1}", this.RootWorkflowExecutor.InstanceIdString, item.ToString()); // running any entry implicitly changes some state of the workflow instance this.RootWorkflowExecutor.stateChangedSincePersistence = true; item.Run(this.RootWorkflowExecutor); } catch (Exception e) { if (WorkflowExecutor.IsIrrecoverableException(e)) { ignoreFinallyBlock = true; throw; } else { if (transactionalProperties != null) { transactionalProperties.TransactionState = TransactionProcessState.AbortProcessed; } exp = e; } } finally { if (!ignoreFinallyBlock) { if (runningItem) { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 1, "Workflow Runtime: Scheduler: InstanceId: {0} : Done with running scheduled entry: {1}", this.RootWorkflowExecutor.InstanceIdString, item.ToString()); } // Process exception // if (exp != null) { // this.RootWorkflowExecutor.ExceptionOccured(exp, itemActivity == null ? contextActivity : itemActivity, null); exp = null; } } } } } while (true); }
public void Run() { Label_0000: this.RootWorkflowExecutor.ProcessQueuedEvents(); SchedulableItem itemToRun = this.GetItemToRun(); bool flag = false; if (itemToRun != null) { Activity currentActivity = null; Exception exp = null; TransactionalProperties transactionalProperties = null; int contextId = itemToRun.ContextId; Activity contextActivityForId = this.RootWorkflowExecutor.GetContextActivityForId(contextId); if (contextActivityForId == null) { throw new InvalidOperationException(ExecutionStringManager.InvalidExecutionContext); } currentActivity = contextActivityForId.GetActivityByName(itemToRun.ActivityId); using (new ServiceEnvironment(currentActivity)) { exp = null; bool flag2 = false; try { if (currentActivity == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidActivityName, new object[] { itemToRun.ActivityId })); } Activity atomicActivity = null; if (this.RootWorkflowExecutor.IsActivityInAtomicContext(currentActivity, out atomicActivity)) { transactionalProperties = (TransactionalProperties)atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty); if (!WorkflowExecutor.CheckAndProcessTransactionAborted(transactionalProperties) && (transactionalProperties.TransactionScope == null)) { transactionalProperties.TransactionScope = new TransactionScope(transactionalProperties.Transaction, TimeSpan.Zero, EnterpriseServicesInteropOption.Full); WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: Scheduler: instanceId: " + this.RootWorkflowExecutor.InstanceIdString + "Entered into TransactionScope, Current atomic acitivity " + atomicActivity.Name); } } flag = true; WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 1, "Workflow Runtime: Scheduler: InstanceId: {0} : Running scheduled entry: {1}", new object[] { this.RootWorkflowExecutor.InstanceIdString, itemToRun.ToString() }); this.RootWorkflowExecutor.stateChangedSincePersistence = true; itemToRun.Run(this.RootWorkflowExecutor); } catch (Exception exception2) { if (WorkflowExecutor.IsIrrecoverableException(exception2)) { flag2 = true; throw; } if (transactionalProperties != null) { transactionalProperties.TransactionState = TransactionProcessState.AbortProcessed; } exp = exception2; } finally { if (!flag2) { if (flag) { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 1, "Workflow Runtime: Scheduler: InstanceId: {0} : Done with running scheduled entry: {1}", new object[] { this.RootWorkflowExecutor.InstanceIdString, itemToRun.ToString() }); } if (exp != null) { this.RootWorkflowExecutor.ExceptionOccured(exp, (currentActivity == null) ? contextActivityForId : currentActivity, null); exp = null; } } } goto Label_0000; } } }