IteratorAsyncResult.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.ServiceModel.Discovery / System / ServiceModel / Discovery / IteratorAsyncResult.cs / 1305376 / IteratorAsyncResult.cs

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

namespace System.ServiceModel.Discovery 
{
    using System.Collections.Generic; 
    using System.Runtime; 
    using System.Threading;
 
    abstract class IteratorAsyncResult : AsyncResult
    {
        TIteratorState iterState;
        TimeoutHelper timeoutHelper; 
        IEnumerator steps;
        bool completedSynchronously; 
        int completedCalled; 
        int numPendingSteps;
        bool shouldComplete; 
        object thisLock;
        AsyncCallback onStepCompletedCallback;

        protected IteratorAsyncResult(AsyncCallback callback, object state) 
            : base(callback, state)
        { 
            this.onStepCompletedCallback = Fx.ThunkCallback(new AsyncCallback(this.OnStepCompleted)); 
            this.thisLock = new object();
        } 

        protected TimeSpan OriginalTimeout
        {
            get { return this.timeoutHelper.OriginalTimeout; } 
        }
 
        public static AsyncStep CallAsync(BeginCall begin, EndCall end) 
        {
            return new AsyncStep(begin, end, false); 
        }

        public static AsyncStep CallAsync(BeginCall begin, EndCall end, IAsyncCatch[] catches)
        { 
            return new AsyncStep(begin, end, false, catches);
        } 
 
        public static AsyncStep CallParallel(BeginCall begin, EndCall end)
        { 
            return new AsyncStep(begin, end, true);
        }

        public static AsyncStep CallParallel(BeginCall begin, EndCall end, IAsyncCatch[] catches) 
        {
            return new AsyncStep(begin, end, true, catches); 
        } 

        protected void Start(TIteratorState iterState, TimeSpan timeout) 
        {
            this.iterState = iterState;
            this.timeoutHelper = new TimeoutHelper(timeout);
            this.completedSynchronously = true; 
            this.steps = this.GetAsyncSteps();
            this.ExecuteSteps(); 
        } 

        protected TimeSpan RemainingTime() 
        {
            return this.timeoutHelper.RemainingTime();
        }
 
        protected abstract IEnumerator GetAsyncSteps();
 
        protected void CompleteOnce() 
        {
            this.CompleteOnce(null); 
        }

        protected void CompleteOnce(Exception error)
        { 
            if (Interlocked.CompareExchange(ref this.completedCalled, 1, 0) == 0)
            { 
                base.Complete(this.completedSynchronously, error); 
            }
        } 

        void ExecuteSteps()
        {
            IAsyncResult result; 
            AsyncStep currentStep;
 
            while (!this.IsCompleted) 
            {
                if (!this.steps.MoveNext()) 
                {
                    this.CompleteIfNoPendingSteps();
                    break;
                } 
                else
                { 
                    currentStep = this.steps.Current; 
                    result = this.StartStep(currentStep);
                    if (result != null) 
                    {
                        if (result.CompletedSynchronously)
                        {
                            this.FinishStep(currentStep, result); 
                        }
                        else if (!currentStep.IsParallel) 
                        { 
                            break;
                        } 
                    }
                }
            }
        } 

        IAsyncResult StartStep(AsyncStep step) 
        { 
            IAsyncResult result = null;
            Exception error = null; 

            try
            {
                this.OnStepStart(); 

                result = step.Begin( 
                    this.iterState, 
                    this.timeoutHelper.RemainingTime(),
                    this.onStepCompletedCallback, 
                    step);
            }
            catch (Exception e)
            { 
                if (Fx.IsFatal(e))
                { 
                    throw; 
                }
 
                error = e;
            }

            if (error != null) 
            {
                this.HandleException(error, step); 
            } 

            return result; 
        }

        void OnStepStart()
        { 
            lock (this.thisLock)
            { 
                this.numPendingSteps++; 
            }
        } 

        void OnStepCompletion()
        {
            bool doComplete = false; 

            lock (this.thisLock) 
            { 
                this.numPendingSteps--;
                if ((this.numPendingSteps == 0) && this.shouldComplete) 
                {
                    doComplete = true;
                }
            } 

            if (doComplete) 
            { 
                this.CompleteOnce();
            } 
        }

        void CompleteIfNoPendingSteps()
        { 
            bool doComplete = false;
 
            lock (this.thisLock) 
            {
                if (this.numPendingSteps == 0) 
                {
                    doComplete = true;
                }
                else 
                {
                    this.shouldComplete = true; 
                } 
            }
 
            if (doComplete)
            {
                this.CompleteOnce();
            } 
        }
 
        void OnStepCompleted(IAsyncResult result) 
        {
            if (result.CompletedSynchronously) 
            {
                return;
            }
 
            this.completedSynchronously = false;
            AsyncStep step = (AsyncStep)result.AsyncState; 
            this.FinishStep(step, result); 

            if (!step.IsParallel) 
            {
                this.ExecuteSteps();
            }
        } 

        void FinishStep(AsyncStep step, IAsyncResult result) 
        { 
            Exception error = null;
 
            try
            {
                step.End(this.iterState, result);
            } 
            catch (Exception e)
            { 
                if (Fx.IsFatal(e)) 
                {
                    throw; 
                }

                error = e;
            } 

            if (error != null) 
            { 
                this.HandleException(error, step);
            } 

            this.OnStepCompletion();
        }
 
        void HandleException(Exception e, AsyncStep step)
        { 
            if (step.Catches != null) 
            {
                Exception outException; 
                for (int i = 0; i < step.Catches.Length; i++)
                {
                    if (step.Catches[i].HandleException(iterState, e, out outException))
                    { 
                        if (outException != null)
                        { 
                            this.CompleteOnce(outException); 
                        }
                        else 
                        {
                            return;
                        }
                    } 
                }
            } 
 
            // The exception wasn't handled
            this.CompleteOnce(e); 
        }

        public delegate IAsyncResult BeginCall(
            TIteratorState iterState, 
            TimeSpan timeout,
            AsyncCallback asyncCallback, 
            object state); 

        public delegate void EndCall(TIteratorState iterState, IAsyncResult result); 

        public delegate Exception ExceptionHandler(TIteratorState iterState, TException exception)
            where TException : Exception;
 
        public class AsyncStep
        { 
            public AsyncStep(BeginCall begin, EndCall end, bool isParallel) 
            {
                this.Begin = begin; 
                this.End = end;
                this.IsParallel = isParallel;
            }
 
            public AsyncStep(BeginCall begin, EndCall end, bool isParallel, IAsyncCatch[] catches)
                : this(begin, end, isParallel) 
            { 
                this.Catches = catches;
            } 

            public IAsyncCatch[] Catches { get; private set; }

            public BeginCall Begin { get; private set; } 

            public EndCall End { get; private set; } 
 
            public bool IsParallel { get; private set; }
        } 

        public interface IAsyncCatch
        {
            bool HandleException(TIteratorState iterState, Exception ex, out Exception outEx); 
        }
 
        public class AsyncCatch : IAsyncCatch 
            where TException : Exception
        { 
            readonly ExceptionHandler handler;

            public AsyncCatch(ExceptionHandler handler)
            { 
                this.handler = handler;
            } 
 
            public bool HandleException(TIteratorState state, Exception ex, out Exception outEx)
            { 
                outEx = null;

                TException casted = ex as TException;
                if (casted != null) 
                {
                    outEx = this.handler(state, casted); 
                    return true; 
                }
                else 
                {
                    // The exception wasn't matched, try next handler
                    return false;
                } 
            }
        } 
    } 
}

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