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; } } }