WorkflowInstance.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Hosting / WorkflowInstance.cs / 1305376 / WorkflowInstance.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Activities.Hosting 
{
    using System; 
    using System.Activities.Runtime; 
    using System.Activities.Tracking;
    using System.Activities.Validation; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization;
    using System.Runtime; 
    using System.Runtime.DurableInstancing; 
    using System.Threading;
    using System.Xml.Linq; 

    [Fx.Tag.XamlVisible(false)]
    public abstract class WorkflowInstance
    { 
        static readonly IDictionary EmptyMappedVariablesDictionary = new ReadOnlyDictionary(new Dictionary(0), false);
 
        const int True = 1; 
        const int False = 0;
 
        WorkflowInstanceControl controller;
        TrackingProvider trackingProvider;
        SynchronizationContext syncContext;
        LocationReferenceEnvironment hostEnvironment; 
        ActivityExecutor executor;
        int isPerformingOperation; 
        bool isInitialized; 
        WorkflowInstanceExtensionCollection extensions;
 
        // Tracking for one-time actions per in-memory instance
        bool hasTrackedResumed;
        bool hasTrackedCompletion;
 
        bool isAborted;
        Exception abortedException; 
 
#if DEBUG
        StackTrace abortStack; 
#endif

        protected WorkflowInstance(Activity workflowDefinition)
        { 
            if (workflowDefinition == null)
            { 
                throw FxTrace.Exception.ArgumentNull("workflowDefinition"); 
            }
 
            this.WorkflowDefinition = workflowDefinition;
        }

        public abstract Guid Id 
        {
            get; 
        } 

        internal bool HasTrackingParticipant 
        {
            get;
            private set;
        } 

        internal bool HasTrackedStarted 
        { 
            get;
            private set; 
        }

        internal bool HasPersistenceModule
        { 
            get;
            private set; 
        } 

        public SynchronizationContext SynchronizationContext 
        {
            get
            {
                return this.syncContext; 
            }
            set 
            { 
                ThrowIfReadOnly();
                this.syncContext = value; 
            }
        }

        public LocationReferenceEnvironment HostEnvironment 
        {
            get 
            { 
                return this.hostEnvironment;
            } 
            set
            {
                ThrowIfReadOnly();
                this.hostEnvironment = value; 
            }
        } 
 
        public Activity WorkflowDefinition
        { 
            get;
            private set;
        }
 
        protected bool IsReadOnly
        { 
            get 
            {
                return this.isInitialized; 
            }
        }

        protected internal abstract bool SupportsInstanceKeys 
        {
            get; 
        } 

        // this is going away 
        internal TrackingProvider TrackingProvider
        {
            get
            { 
                Fx.Assert(HasTrackingParticipant, "we should only be called if we have a tracking participant");
                return this.trackingProvider; 
            } 
        }
 
        protected WorkflowInstanceControl Controller
        {
            get
            { 
                if (!this.isInitialized)
                { 
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ControllerInvalidBeforeInitialize)); 
                }
 
                return this.controller;
            }
        }
 
        // host-facing access to our cascading ExtensionManager resolution
        protected internal T GetExtension() where T : class 
        { 
            if (this.extensions != null)
            { 
                return this.extensions.Find();
            }
            else
            { 
                return default(T);
            } 
        } 

        protected internal IEnumerable GetExtensions() where T : class 
        {
            if (this.extensions != null)
            {
                return this.extensions.FindAll(); 
            }
            else 
            { 
                return new T[0];
            } 
        }

        // locks down the given extensions manager and runs cache metadata on the workflow definition
        protected void RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager) 
        {
            ValidateWorkflow(extensionManager); 
            this.extensions = WorkflowInstanceExtensionManager.CreateInstanceExtensions(this.WorkflowDefinition, extensionManager); 
            if (this.extensions != null)
            { 
                this.HasPersistenceModule = this.extensions.HasPersistenceModule;
            }
        }
 
        // dispose the extensions that implement IDisposable
        protected void DisposeExtensions() 
        { 
            if (this.extensions != null)
            { 
                this.extensions.Dispose();
                this.extensions = null;
            }
        } 

        // used for Create scenarios where you are providing root information 
        protected void Initialize(IDictionary workflowArgumentValues, IList workflowExecutionProperties) 
        {
            ThrowIfAborted(); 
            ThrowIfReadOnly();
            this.executor = new ActivityExecutor(this);

            // workflowArgumentValues signals whether we are a new or loaded instance, so we can't pass in null. 
            // workflowExecutionProperties is allowed to be null
            InitializeCore(workflowArgumentValues ?? ActivityUtilities.EmptyParameters, workflowExecutionProperties); 
        } 

        // used for Load scenarios where you are rehydrating a WorkflowInstance 
        protected void Initialize(object deserializedRuntimeState)
        {
            ThrowIfAborted();
            ThrowIfReadOnly(); 
            this.executor = deserializedRuntimeState as ActivityExecutor;
 
            if (this.executor == null) 
            {
                throw FxTrace.Exception.Argument("deserializedRuntimeState", SR.InvalidRuntimeState); 
            }

            InitializeCore(null, null);
        } 

        void ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager) 
        { 
            if (!WorkflowDefinition.IsRuntimeReady)
            { 
                LocationReferenceEnvironment localEnvironment = this.hostEnvironment;
                if (localEnvironment == null)
                {
                    LocationReferenceEnvironment parentEnvironment = null; 
                    if (extensionManager != null && extensionManager.SymbolResolver != null)
                    { 
                        parentEnvironment = extensionManager.SymbolResolver.AsLocationReferenceEnvironment(); 
                    }
                    localEnvironment = new ActivityLocationReferenceEnvironment(parentEnvironment); 
                }
                IList validationErrors = null;
                ActivityUtilities.CacheRootMetadata(WorkflowDefinition, localEnvironment, ProcessActivityTreeOptions.FullCachingOptions, null, ref validationErrors);
                ActivityValidationServices.ThrowIfViolationsExist(validationErrors); 
            }
        } 
 
        void InitializeCore(IDictionary workflowArgumentValues, IList workflowExecutionProperties)
        { 
            Fx.Assert(this.executor != null, "at this point, we better have an executor");

            if (this.extensions != null)
            { 
                this.extensions.Initialize();
                if (this.extensions.HasTrackingParticipant) 
                { 
                    this.HasTrackingParticipant = true;
                    this.trackingProvider = new TrackingProvider(this.WorkflowDefinition); 
                    foreach (TrackingParticipant trackingParticipant in GetExtensions())
                    {
                        this.trackingProvider.AddParticipant(trackingParticipant);
                    } 
                }
            } 
            else 
            {
                // need to ensure the workflow has been validated since the host isn't using extensions (and so didn't register anything) 
                ValidateWorkflow(null);
            }

            // Do Argument validation for root activities 
            WorkflowDefinition.HasBeenAssociatedWithAnInstance = true;
 
            if (workflowArgumentValues != null) 
            {
                IDictionary actualInputs = workflowArgumentValues; 

                if (object.ReferenceEquals(actualInputs, ActivityUtilities.EmptyParameters))
                {
                    actualInputs = null; 
                }
 
                if (this.WorkflowDefinition.RuntimeArguments.Count > 0 || (actualInputs != null && actualInputs.Count > 0)) 
                {
                    ActivityValidationServices.ValidateRootInputs(this.WorkflowDefinition, actualInputs); 
                }

                this.executor.ScheduleRootActivity(this.WorkflowDefinition, actualInputs, workflowExecutionProperties);
            } 
            else
            { 
                this.executor.OnDeserialized(this.WorkflowDefinition, this); 
            }
 
            this.executor.Open(this.SynchronizationContext);
            this.controller = new WorkflowInstanceControl(this, this.executor);
            this.isInitialized = true;
 
            if (this.extensions != null && this.extensions.HasWorkflowInstanceExtensions)
            { 
                WorkflowInstanceProxy proxy = new WorkflowInstanceProxy(this); 

                for (int i = 0; i < this.extensions.WorkflowInstanceExtensions.Count; i++) 
                {
                    IWorkflowInstanceExtension extension = this.extensions.WorkflowInstanceExtensions[i];
                    extension.SetInstance(proxy);
                } 
            }
        } 
 
        protected void ThrowIfReadOnly()
        { 
            if (this.isInitialized)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WorkflowInstanceIsReadOnly(this.Id)));
            } 
        }
 
        protected internal abstract IAsyncResult OnBeginResumeBookmark(Bookmark bookmark, object value, TimeSpan timeout, AsyncCallback callback, object state); 
        protected internal abstract BookmarkResumptionResult OnEndResumeBookmark(IAsyncResult result);
 
        protected internal abstract IAsyncResult OnBeginPersist(AsyncCallback callback, object state);
        protected internal abstract void OnEndPersist(IAsyncResult result);

        protected internal abstract void OnDisassociateKeys(ICollection keys); 

        protected internal abstract IAsyncResult OnBeginAssociateKeys(ICollection keys, AsyncCallback callback, object state); 
        protected internal abstract void OnEndAssociateKeys(IAsyncResult result); 

        internal IAsyncResult BeginFlushTrackingRecords(AsyncCallback callback, object state) 
        {
            return OnBeginFlushTrackingRecords(callback, state);
        }
 
        internal void EndFlushTrackingRecords(IAsyncResult result)
        { 
            OnEndFlushTrackingRecords(result); 
        }
 
        protected virtual IAsyncResult OnBeginFlushTrackingRecords(AsyncCallback callback, object state)
        {
            return this.Controller.BeginFlushTrackingRecords(ActivityDefaults.TrackingTimeout, callback, state);
        } 

        protected virtual void OnEndFlushTrackingRecords(IAsyncResult result) 
        { 
            this.Controller.EndFlushTrackingRecords(result);
        } 

        internal void NotifyPaused()
        {
            if (this.executor.State != ActivityInstanceState.Executing) 
            {
                TrackCompletion(); 
            } 

            OnNotifyPaused(); 
        }

        protected abstract void OnNotifyPaused();
 
        internal void NotifyUnhandledException(Exception exception, Activity source, string sourceInstanceId)
        { 
            if (this.controller.TrackingEnabled) 
            {
                ActivityInfo faultSourceInfo = new ActivityInfo(source.DisplayName, source.Id, sourceInstanceId, source.GetType().FullName); 
                this.controller.Track(new WorkflowInstanceUnhandledExceptionRecord(this.Id, this.WorkflowDefinition.DisplayName, faultSourceInfo, exception));
            }

            OnNotifyUnhandledException(exception, source, sourceInstanceId); 
        }
 
        protected abstract void OnNotifyUnhandledException(Exception exception, Activity source, string sourceInstanceId); 

        protected internal abstract void OnRequestAbort(Exception reason); 

        internal void OnDeserialized(bool hasTrackedStarted)
        {
            this.HasTrackedStarted = hasTrackedStarted; 
        }
 
        void StartOperation(ref bool resetRequired) 
        {
            StartReadOnlyOperation(ref resetRequired); 

            // isRunning can only flip to true by an operation and therefore
            // we don't have to worry about this changing under us
            if (this.executor.IsRunning) 
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.RuntimeRunning)); 
            } 
        }
 
        void StartReadOnlyOperation(ref bool resetRequired)
        {
            bool wasPerformingOperation = false;
            try 
            {
            } 
            finally 
            {
                wasPerformingOperation = Interlocked.CompareExchange(ref this.isPerformingOperation, True, False) == True; 

                if (!wasPerformingOperation)
                {
                    resetRequired = true; 
                }
            } 
 
            if (wasPerformingOperation)
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.RuntimeOperationInProgress));
            }
        }
 
        void FinishOperation(ref bool resetRequired)
        { 
            if (resetRequired) 
            {
                this.isPerformingOperation = False; 
            }
        }

        internal void Abort(Exception reason) 
        {
            if (!this.isAborted) 
            { 
                this.isAborted = true;
                if (reason != null) 
                {
                    this.abortedException = reason;
                }
 
                if (this.extensions != null)
                { 
                    this.extensions.Cancel(); 
                }
 
                if (this.controller.TrackingEnabled)
                {
                    // During abort we only track this one record
                    if (reason != null) 
                    {
                        string message = reason.Message; 
                        if (reason.InnerException != null) 
                        {
                            message = SR.WorkflowAbortedReason(reason.Message, reason.InnerException.Message); 
                        }
                        this.controller.Track(new WorkflowInstanceAbortedRecord(this.Id, this.WorkflowDefinition.DisplayName, message));
                    }
                } 
#if DEBUG
                if (!Fx.FastDebug) 
                { 
                    if (reason != null)
                    { 
                        reason.ToString();
                    }
                    this.abortStack = new StackTrace();
                } 
#endif
            } 
        } 

        void ValidatePrepareForSerialization() 
        {
            ThrowIfAborted();
            if (!this.Controller.IsPersistable)
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.PrepareForSerializationRequiresPersistability));
            } 
        } 

        void ValidateScheduleResumeBookmark() 
        {
            ThrowIfAborted();
            ThrowIfNotIdle();
        } 

        void ValidateGetBookmarks() 
        { 
            ThrowIfAborted();
        } 

        void ValidateGetMappedVariables()
        {
            ThrowIfAborted(); 
        }
 
        void ValidatePauseWhenPersistable() 
        {
            ThrowIfAborted(); 
            if (this.Controller.IsPersistable)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.PauseWhenPersistableInvalidIfPersistable));
            } 
        }
 
        void Terminate(Exception reason) 
        {
            // validate we're in an ok state 
            ThrowIfAborted();

            // terminate the runtime
            this.executor.Terminate(reason); 

            // and track if necessary 
            TrackCompletion(); 

        } 

        void TrackCompletion()
        {
            if (this.controller.TrackingEnabled && !this.hasTrackedCompletion) 
            {
                ActivityInstanceState completionState = this.executor.State; 
 
                if (completionState == ActivityInstanceState.Faulted)
                { 
                    Fx.Assert(this.executor.TerminationException != null, "must have a termination exception if we're faulted");
                    this.controller.Track(new WorkflowInstanceTerminatedRecord(this.Id, this.WorkflowDefinition.DisplayName, this.executor.TerminationException.Message));
                }
                else if (completionState == ActivityInstanceState.Closed) 
                {
                    this.controller.Track(new WorkflowInstanceRecord(this.Id, this.WorkflowDefinition.DisplayName, WorkflowInstanceStates.Completed)); 
                } 
                else
                { 
                    Fx.AssertAndThrow(completionState == ActivityInstanceState.Canceled, "Cannot be executing a workflow instance when WorkflowState was completed.");
                    this.controller.Track(new WorkflowInstanceRecord(this.Id, this.WorkflowDefinition.DisplayName, WorkflowInstanceStates.Canceled));
                }
                this.hasTrackedCompletion = true; 
            }
        } 
 
        void TrackResumed()
        { 
            // track if necessary
            if (!this.hasTrackedResumed)
            {
                if (this.Controller.TrackingEnabled) 
                {
                    if (!this.HasTrackedStarted) 
                    { 
                        this.TrackingProvider.AddRecord(new WorkflowInstanceRecord(this.Id, this.WorkflowDefinition.DisplayName, WorkflowInstanceStates.Started));
                        this.HasTrackedStarted = true; 
                    }
                    else
                    {
                        this.TrackingProvider.AddRecord(new WorkflowInstanceRecord(this.Id, this.WorkflowDefinition.DisplayName, WorkflowInstanceStates.Resumed)); 
                    }
                } 
                this.hasTrackedResumed = true; 
            }
        } 

        void Run()
        {
            // validate we're in an ok state 
            ThrowIfAborted();
 
            TrackResumed(); 

            // and let the scheduler go 
            this.executor.MarkSchedulerRunning();
        }

        void ScheduleCancel() 
        {
            // validate we're in an ok state 
            ThrowIfAborted(); 

            TrackResumed(); 

            this.executor.CancelRootActivity();
        }
 
        BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value)
        { 
            // validate we're in an ok state 
            ValidateScheduleResumeBookmark();
 
            TrackResumed();

            return this.executor.TryResumeHostBookmark(bookmark, value);
        } 

        BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope) 
        { 
            // validate we're in an ok state
            ValidateScheduleResumeBookmark(); 

            TrackResumed();

            return this.executor.TryResumeBookmark(bookmark, value, scope); 
        }
 
 
        void ThrowIfAborted()
        { 
            if (this.isAborted || (this.executor != null && this.executor.IsAbortPending))
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WorkflowInstanceAborted(this.Id)));
            } 
        }
 
        void ThrowIfNotIdle() 
        {
            if (!this.executor.IsIdle) 
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarksOnlyResumableWhileIdle));
            }
        } 

        [SuppressMessage(FxCop.Category.Design, FxCop.Rule.NestedTypesShouldNotBeVisible, 
            Justification = "these are effectively protected methods, but encapsulated in a struct to avoid naming conflicts")] 
        protected struct WorkflowInstanceControl
        { 
            ActivityExecutor executor;
            WorkflowInstance instance;

            internal WorkflowInstanceControl(WorkflowInstance instance, ActivityExecutor executor) 
            {
                this.instance = instance; 
                this.executor = executor; 
            }
 
            public bool IsPersistable
            {
                get
                { 
                    return this.executor.IsPersistable;
                } 
            } 

            public bool HasPendingTrackingRecords 
            {
                get
                {
                    return this.instance.HasTrackingParticipant && this.instance.TrackingProvider.HasPendingRecords; 
                }
            } 
 
            public bool TrackingEnabled
            { 
                get
                {
                    return this.instance.HasTrackingParticipant && this.instance.TrackingProvider.ShouldTrackWorkflowInstanceRecords;
                } 
            }
 
            public WorkflowInstanceState State 
            {
                get 
                {
                    WorkflowInstanceState result;

                    if (this.instance.isAborted) 
                    {
                        result = WorkflowInstanceState.Aborted; 
                    } 
                    else if (!this.executor.IsIdle)
                    { 
                        result = WorkflowInstanceState.Runnable;
                    }
                    else
                    { 
                        if (this.executor.State == ActivityInstanceState.Executing)
                        { 
                            result = WorkflowInstanceState.Idle; 
                        }
                        else 
                        {
                            result = WorkflowInstanceState.Complete;
                        }
                    } 

                    return result; 
                } 
            }
 
            public override bool Equals(object obj)
            {
                if (!(obj is WorkflowInstanceControl))
                { 
                    return false;
                } 
 
                WorkflowInstanceControl other = (WorkflowInstanceControl)obj;
                return other.instance == this.instance; 
            }

            public override int GetHashCode()
            { 
                return this.instance.GetHashCode();
            } 
 
            public static bool operator ==(WorkflowInstanceControl left, WorkflowInstanceControl right)
            { 
                return left.Equals(right);
            }

            public static bool operator !=(WorkflowInstanceControl left, WorkflowInstanceControl right) 
            {
                return !left.Equals(right); 
            } 

            public ReadOnlyCollection GetBookmarks() 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartReadOnlyOperation(ref resetRequired); 
 
                    this.instance.ValidateGetBookmarks();
 
                    return this.executor.GetAllBookmarks();
                }
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            } 

            public ReadOnlyCollection GetBookmarks(BookmarkScope scope) 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartReadOnlyOperation(ref resetRequired); 
 
                    this.instance.ValidateGetBookmarks();
 
                    return this.executor.GetBookmarks(scope);
                }
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            } 

            public IDictionary GetMappedVariables() 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartReadOnlyOperation(ref resetRequired); 
 
                    this.instance.ValidateGetMappedVariables();
 
                    IDictionary mappedLocations = this.instance.executor.GatherMappableVariables();
                    if (mappedLocations != null)
                    {
                        mappedLocations = new ReadOnlyDictionary(mappedLocations, false); 
                    }
                    else 
                    { 
                        mappedLocations = WorkflowInstance.EmptyMappedVariablesDictionary;
                    } 
                    return mappedLocations;
                }
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            } 

            public void Run() 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartOperation(ref resetRequired); 
 
                    this.instance.Run();
                } 
                finally
                {
                    this.instance.FinishOperation(ref resetRequired);
                } 

                this.executor.Run(); 
            } 

            public void RequestPause() 
            {
                // No validations for this because we do not
                // require calls to Pause to be synchronized
                // by the caller 
                this.executor.PauseScheduler();
            } 
 
            // Calls Pause when IsPersistable goes from false->true
            public void PauseWhenPersistable() 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartOperation(ref resetRequired); 
 
                    this.instance.ValidatePauseWhenPersistable();
 
                    this.executor.PauseWhenPersistable();
                }
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            } 

            public void ScheduleCancel() 
            {
                bool resetRequired = false;

                try 
                {
                    this.instance.StartOperation(ref resetRequired); 
 
                    this.instance.ScheduleCancel();
                } 
                finally
                {
                    this.instance.FinishOperation(ref resetRequired);
                } 
            }
 
            public void Terminate(Exception reason) 
            {
                bool resetRequired = false; 

                try
                {
                    this.instance.StartOperation(ref resetRequired); 

                    this.instance.Terminate(reason); 
                } 
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                }
            }
 
            public BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value)
            { 
                bool resetRequired = false; 

                try 
                {
                    this.instance.StartOperation(ref resetRequired);

                    return this.instance.ScheduleBookmarkResumption(bookmark, value); 
                }
                finally 
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            }

            public BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope)
            { 
                bool resetRequired = false;
 
                try 
                {
                    this.instance.StartOperation(ref resetRequired); 

                    return this.instance.ScheduleBookmarkResumption(bookmark, value, scope);
                }
                finally 
                {
                    this.instance.FinishOperation(ref resetRequired); 
                } 
            }
 
            public void Abort()
            {
                bool resetRequired = false;
 
                try
                { 
                    this.instance.StartOperation(ref resetRequired); 

                    // No validations 

                    this.executor.Dispose();

                    this.instance.Abort(null); 
                }
                finally 
                { 
                    this.instance.FinishOperation(ref resetRequired);
                } 
            }

            public void Abort(Exception reason)
            { 
                bool resetRequired = false;
 
                try 
                {
                    this.instance.StartOperation(ref resetRequired); 

                    // No validations

                    this.executor.Abort(reason); 

                    this.instance.Abort(reason); 
                } 
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired);
                }
            }
 
            [SuppressMessage(FxCop.Category.Design, FxCop.Rule.ConsiderPassingBaseTypesAsParameters,
                Justification = "Only want to allow WorkflowInstanceRecord subclasses for WorkflowInstance-level tracking")] 
            public void Track(WorkflowInstanceRecord instanceRecord) 
            {
                if (this.instance.HasTrackingParticipant) 
                {
                    this.instance.TrackingProvider.AddRecord(instanceRecord);
                }
            } 

            public void FlushTrackingRecords(TimeSpan timeout) 
            { 
                if (this.instance.HasTrackingParticipant)
                { 
                    this.instance.TrackingProvider.FlushPendingRecords(timeout);
                }
            }
 
            public IAsyncResult BeginFlushTrackingRecords(TimeSpan timeout, AsyncCallback callback, object state)
            { 
                if (this.instance.HasTrackingParticipant) 
                {
                    return this.instance.TrackingProvider.BeginFlushPendingRecords(timeout, callback, state); 
                }
                else
                {
                    return new CompletedAsyncResult(callback, state); 
                }
            } 
 
            public void EndFlushTrackingRecords(IAsyncResult result)
            { 
                if (this.instance.HasTrackingParticipant)
                {
                    this.instance.TrackingProvider.EndFlushPendingRecords(result);
                } 
                else
                { 
                    CompletedAsyncResult.End(result); 
                }
            } 

            public object PrepareForSerialization()
            {
                bool resetRequired = false; 

                try 
                { 
                    this.instance.StartReadOnlyOperation(ref resetRequired);
 
                    this.instance.ValidatePrepareForSerialization();

                    return this.executor.PrepareForSerialization();
                } 
                finally
                { 
                    this.instance.FinishOperation(ref resetRequired); 
                }
            } 

            public ActivityInstanceState GetCompletionState()
            {
                return this.executor.State; 
            }
 
            [SuppressMessage(FxCop.Category.Design, FxCop.Rule.AvoidOutParameters, 
                Justification = "Arch approved design. Requires the out argument for extra information provided")]
            public ActivityInstanceState GetCompletionState(out Exception terminationException) 
            {
                terminationException = this.executor.TerminationException;
                return this.executor.State;
            } 

            [SuppressMessage(FxCop.Category.Design, FxCop.Rule.AvoidOutParameters, 
                Justification = "Arch approved design. Requires the out argument for extra information provided")] 
            public ActivityInstanceState GetCompletionState(out IDictionary outputs, out Exception terminationException)
            { 
                outputs = this.executor.WorkflowOutputs;
                terminationException = this.executor.TerminationException;
                return this.executor.State;
            } 

            public Exception GetAbortReason() 
            { 
                return this.instance.abortedException;
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK