WorkItem.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 / Runtime / WorkItem.cs / 1305376 / WorkItem.cs

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

namespace System.Activities.Runtime 
{
    using System; 
    using System.Runtime; 
    using System.Reflection;
    using System.Runtime.DurableInstancing; 
    using System.Runtime.Serialization;
    using System.Diagnostics.CodeAnalysis;
    using System.Activities.Debugger;
    using System.Collections.Generic; 
    using System.Activities.Tracking;
 
    [DataContract] 
    abstract class WorkItem
    { 
        static AsyncCallback associateCallback;
        static AsyncCallback trackingCallback;

        // We use a protected field here because it works well with 
        // ref style Cleanup exception handling.
        protected Exception workflowAbortException; 
 
        [DataMember]
        ActivityInstance activityInstance; 

        Exception exceptionToPropagate;

        // Used by subclasses in the pooled case. 
        protected WorkItem()
        { 
        } 

        protected WorkItem(ActivityInstance activityInstance) 
        {
            this.activityInstance = activityInstance;
            this.activityInstance.IncrementBusyCount();
        } 

        public ActivityInstance ActivityInstance 
        { 
            get
            { 
                return this.activityInstance;
            }
        }
 
        public Exception WorkflowAbortException
        { 
            get 
            {
                return this.workflowAbortException; 
            }
        }

        public Exception ExceptionToPropagate 
        {
            get 
            { 
                return this.exceptionToPropagate;
            } 
            set
            {
                Fx.Assert(value != null, "We should never set this back to null explicitly.  Use the ExceptionPropagated method below.");
 
                this.exceptionToPropagate = value;
            } 
        } 

        public abstract ActivityInstance PropertyManagerOwner 
        {
            get;
        }
 
        public virtual ActivityInstance OriginalExceptionSource
        { 
            get 
            {
                return this.ActivityInstance; 
            }
        }

        [DataMember(EmitDefaultValue = false)] 
        public bool IsEmpty
        { 
            get; 
            protected set;
        } 

        public bool ExitNoPersistRequired
        {
            get; 
            protected set;
        } 
 
        protected bool IsPooled
        { 
            get;
            set;
        }
 
        public abstract bool IsValid
        { 
            get; 
        }
 
        public void Dispose(ActivityExecutor executor)
        {
            if (FxTrace.ShouldTraceVerboseToTraceSource)
            { 
                TraceCompleted();
            } 
 
            if (this.IsPooled)
            { 
                this.ReleaseToPool(executor);
            }
        }
 
        protected virtual void ClearForReuse()
        { 
            this.exceptionToPropagate = null; 
            this.workflowAbortException = null;
            this.activityInstance = null; 
        }

        protected virtual void Reinitialize(ActivityInstance activityInstance)
        { 
            this.activityInstance = activityInstance;
            this.activityInstance.IncrementBusyCount(); 
        } 

        // this isn't just public for performance reasons. We avoid the virtual call 
        // by going through Dispose()
        protected virtual void ReleaseToPool(ActivityExecutor executor)
        {
            Fx.Assert("This should never be called ... only overridden versions should get called."); 
        }
 
        static void OnAssociateComplete(IAsyncResult result) 
        {
            if (result.CompletedSynchronously) 
            {
                return;
            }
 
            CallbackData data = (CallbackData)result.AsyncState;
 
            try 
            {
                data.Executor.EndAssociateKeys(result); 
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) 
                {
                    throw; 
                } 

                data.WorkItem.workflowAbortException = e; 
            }

            data.Executor.FinishWorkItem(data.WorkItem);
        } 

        static void OnTrackingComplete(IAsyncResult result) 
        { 
            if (result.CompletedSynchronously)
            { 
                return;
            }

            CallbackData data = (CallbackData)result.AsyncState; 

            try 
            { 
                data.Executor.EndTrackPendingRecords(result);
            } 
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                { 
                    throw;
                } 
 
                data.WorkItem.workflowAbortException = e;
            } 

            data.Executor.FinishWorkItemAfterTracking(data.WorkItem);
        }
 
        public void ExceptionPropagated()
        { 
            // We just null this out, but using this API helps with 
            // readability over the property setter
            this.exceptionToPropagate = null; 
        }

        public void Release(ActivityExecutor executor)
        { 
            this.activityInstance.DecrementBusyCount();
 
            if (this.ExitNoPersistRequired) 
            {
                executor.ExitNoPersist(); 
            }
        }

        public abstract void TraceScheduled(); 

        protected void TraceRuntimeWorkItemScheduled() 
        { 
            if (TD.ScheduleRuntimeWorkItemIsEnabled())
            { 
                TD.ScheduleRuntimeWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id);
            }
        }
 
        public abstract void TraceStarting();
 
        protected void TraceRuntimeWorkItemStarting() 
        {
            if (TD.StartRuntimeWorkItemIsEnabled()) 
            {
                TD.StartRuntimeWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id);
            }
        } 

        public abstract void TraceCompleted(); 
 
        protected void TraceRuntimeWorkItemCompleted()
        { 
            if (TD.CompleteRuntimeWorkItemIsEnabled())
            {
                TD.CompleteRuntimeWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id);
            } 
        }
 
        public abstract bool Execute(ActivityExecutor executor, BookmarkManager bookmarkManager); 

        public abstract void PostProcess(ActivityExecutor executor); 

        public bool FlushBookmarkScopeKeys(ActivityExecutor executor)
        {
            Fx.Assert(executor.BookmarkScopeManager.HasKeysToUpdate, "We should not have been called if we don't have pending keys."); 

            try 
            { 
                // disassociation is local-only so we don't need to yield
                ICollection keysToDisassociate = executor.BookmarkScopeManager.GetKeysToDisassociate(); 
                if (keysToDisassociate != null && keysToDisassociate.Count > 0)
                {
                    executor.DisassociateKeys(keysToDisassociate);
                } 

                // if we have keys to associate, provide them for an asynchronous association 
                ICollection keysToAssociate = executor.BookmarkScopeManager.GetKeysToAssociate(); 

                // It could be that we only had keys to Disassociate. We should only do BeginAssociateKeys 
                // if we have keysToAssociate.
                if (keysToAssociate != null && keysToAssociate.Count > 0)
                {
                    if (associateCallback == null) 
                    {
                        associateCallback = Fx.ThunkCallback(new AsyncCallback(OnAssociateComplete)); 
                    } 

                    IAsyncResult result = executor.BeginAssociateKeys(keysToAssociate, associateCallback, new CallbackData(executor, this)); 
                    if (result.CompletedSynchronously)
                    {
                        executor.EndAssociateKeys(result);
                    } 
                    else
                    { 
                        return false; 
                    }
                } 
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) 
                {
                    throw; 
                } 

                this.workflowAbortException = e; 
            }

            return true;
        } 

        public bool FlushTracking(ActivityExecutor executor) 
        { 
            Fx.Assert(executor.HasPendingTrackingRecords, "We should not have been called if we don't have pending tracking records");
 
            try
            {
                if (trackingCallback == null)
                { 
                    trackingCallback = Fx.ThunkCallback(new AsyncCallback(OnTrackingComplete));
                } 
 
                IAsyncResult result = executor.BeginTrackPendingRecords(
                    trackingCallback, 
                    new CallbackData(executor, this));

                if (result.CompletedSynchronously)
                { 
                    executor.EndTrackPendingRecords(result);
                } 
                else 
                {
                    // Completed async so we'll return false 
                    return false;
                }
            }
            catch (Exception e) 
            {
                if (Fx.IsFatal(e)) 
                { 
                    throw;
                } 

                this.workflowAbortException = e;
            }
 
            return true;
        } 
 
        class CallbackData
        { 
            public CallbackData(ActivityExecutor executor, WorkItem workItem)
            {
                this.Executor = executor;
                this.WorkItem = workItem; 
            }
 
            public ActivityExecutor Executor 
            {
                get; 
                private set;
            }

            public WorkItem WorkItem 
            {
                get; 
                private set; 
            }
        } 
    }
}

// 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