BaseAsyncResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / BaseAsyncResult.cs / 1 / BaseAsyncResult.cs

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

namespace System.Data.Services.Client 
{
    using System;
    using System.Diagnostics;
    using System.IO; 
#if !ASTORIA_LIGHT // Data.Services http stack
    using System.Net; 
#else 
    using System.Data.Services.Http;
#endif 

    /// 
    /// Implementation of IAsyncResult
    ///  
    internal abstract class BaseAsyncResult : IAsyncResult
    { 
        /// Originating object, used to validate End* 
        internal readonly object Source;
 
        /// Originating method on source, to differentiate between different methods from same source
        internal readonly string Method;

        /// User callback passed to Begin* 
        private readonly AsyncCallback userCallback;
 
        /// User state passed to Begin* 
        private readonly object userState;
 
        /// wait handle for user to wait until done
        private System.Threading.ManualResetEvent asyncWait;

        /// Holding exception to throw as a nested exception during to End* 
        private Exception failure;
 
        /// true unless something completes asynchronously 
        private bool completedSynchronously = true;
 
        /// true when no more changes are pending
        private bool completed;

        /// verify we only invoke the user callback once 
        private int userNotified;
 
        /// non-zero after End* 
        private int done;
 
        /// 
        /// ctor
        /// 
        /// source object of async request 
        /// async method name on source object
        /// user callback to invoke when complete 
        /// user state 
        internal BaseAsyncResult(object source, string method, AsyncCallback callback, object state)
        { 
            Debug.Assert(null != source, "null source");
            this.Source = source;
            this.Method = method;
            this.userCallback = callback; 
            this.userState = state;
        } 
 
        #region IAsyncResult implmentation - AsyncState, AsyncWaitHandle, CompletedSynchronously, IsCompleted
 
        /// user state object parameter
        public object AsyncState
        {
            get { return this.userState; } 
        }
 
        /// wait handle for when waiting is required 
        /// if displayed by debugger, it undesirable to create the WaitHandle
        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
        public System.Threading.WaitHandle AsyncWaitHandle
        {
            get
            { 
                if (null == this.asyncWait)
                {   // delay create the wait handle since the user may never use it 
                    // like asyncWait which will be GC'd, the losers in creating the asyncWait will also be GC'd 
                    System.Threading.Interlocked.CompareExchange(ref this.asyncWait, new System.Threading.ManualResetEvent(this.IsCompleted), null);
 
                    // multi-thread condition
                    // 1) thread 1 returned IAsyncResult and !IsCompleted so AsyncWaitHandle.WaitOne()
                    // 2) thread 2 signals complete, however thread 1 has retrieved this.completed but not assigned asyncWait
                    if (this.IsCompleted) 
                    {   // yes, Set may be called multiple times - but user would have to assume ManualResetEvent and call Reset
                        this.asyncWait.Set(); 
                    } 
                }
 
                return this.asyncWait;
            }
        }
 
        /// did the result complete synchronously?
        public bool CompletedSynchronously 
        { 
            get { return this.completedSynchronously; }
            internal set { this.completedSynchronously = value; } 
        }

        /// is the result complete?
        public bool IsCompleted 
        {
            get { return this.completed; } 
            internal set { this.completed = value; } 
        }
 
        #endregion

        /// first exception that happened
        internal Exception Failure 
        {
            get { return this.failure; } 
        } 

        ///  
        /// common handler for EndExecuteBatch & EndSaveChanges
        /// 
        /// derived type of the AsyncResult
        /// source object of async request 
        /// async method name on source object
        /// the asyncResult being ended 
        /// data service response for batch 
        internal static T EndExecute(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult
        { 
            Util.CheckArgumentNull(asyncResult, "asyncResult");

            T result = (asyncResult as T);
            if ((null == result) || (source != result.Source) || (result.Method != method)) 
            {
                throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); 
            } 

            Debug.Assert((result.CompletedSynchronously && result.IsCompleted) || !result.CompletedSynchronously, "CompletedSynchronously && !IsCompleted"); 

            if (!result.IsCompleted)
            {   // if the user doesn't want to wait forever, they should explictly wait on the handle with a timeout
                result.AsyncWaitHandle.WaitOne(); 

                Debug.Assert(result.IsCompleted, "not completed after waiting"); 
            } 

            if (System.Threading.Interlocked.Exchange(ref result.done, 1) != 0) 
            {
                throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult");
            }
 
            if (null != result.failure)
            { 
                throw Error.InvalidOperation(Strings.Context_SaveChangesError, result.failure); 
            }
 
            return result;
        }

        /// Set the AsyncWait and invoke the user callback. 
        internal void HandleCompleted()
        { 
            if (Util.DoNotHandleException(this.failure)) 
            {
                return; 
            }

            if (this.IsCompleted && (System.Threading.Interlocked.Exchange(ref this.userNotified, 1) == 0))
            { 
                try
                { 
                    this.CompletedRequest(); 
                }
                catch (Exception ex) 
                {
                    if (this.HandleFailure(ex))
                    {
                        throw; 
                    }
                } 
 
                if (null != this.asyncWait)
                { 
                    this.asyncWait.Set();
                }

                if (null != this.userCallback) 
                {   // any exception thrown by user should be "unhandled"
                    this.userCallback(this); 
                } 
            }
        } 

        /// Cache the exception that happened on the background thread for the caller of EndSaveChanges.
        /// exception object from background thread
        /// true if the exception (like StackOverflow or ThreadAbort) should be rethrown 
        internal bool HandleFailure(Exception e)
        { 
            System.Threading.Interlocked.CompareExchange(ref this.failure, e, null); 
            this.completed = true;
            return Util.DoNotHandleException(e); 
        }

        /// invoked for derived classes to cleanup before callback is invoked
        protected abstract void CompletedRequest(); 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
// query object
//  
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client 
{
    using System;
    using System.Diagnostics;
    using System.IO; 
#if !ASTORIA_LIGHT // Data.Services http stack
    using System.Net; 
#else 
    using System.Data.Services.Http;
#endif 

    /// 
    /// Implementation of IAsyncResult
    ///  
    internal abstract class BaseAsyncResult : IAsyncResult
    { 
        /// Originating object, used to validate End* 
        internal readonly object Source;
 
        /// Originating method on source, to differentiate between different methods from same source
        internal readonly string Method;

        /// User callback passed to Begin* 
        private readonly AsyncCallback userCallback;
 
        /// User state passed to Begin* 
        private readonly object userState;
 
        /// wait handle for user to wait until done
        private System.Threading.ManualResetEvent asyncWait;

        /// Holding exception to throw as a nested exception during to End* 
        private Exception failure;
 
        /// true unless something completes asynchronously 
        private bool completedSynchronously = true;
 
        /// true when no more changes are pending
        private bool completed;

        /// verify we only invoke the user callback once 
        private int userNotified;
 
        /// non-zero after End* 
        private int done;
 
        /// 
        /// ctor
        /// 
        /// source object of async request 
        /// async method name on source object
        /// user callback to invoke when complete 
        /// user state 
        internal BaseAsyncResult(object source, string method, AsyncCallback callback, object state)
        { 
            Debug.Assert(null != source, "null source");
            this.Source = source;
            this.Method = method;
            this.userCallback = callback; 
            this.userState = state;
        } 
 
        #region IAsyncResult implmentation - AsyncState, AsyncWaitHandle, CompletedSynchronously, IsCompleted
 
        /// user state object parameter
        public object AsyncState
        {
            get { return this.userState; } 
        }
 
        /// wait handle for when waiting is required 
        /// if displayed by debugger, it undesirable to create the WaitHandle
        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
        public System.Threading.WaitHandle AsyncWaitHandle
        {
            get
            { 
                if (null == this.asyncWait)
                {   // delay create the wait handle since the user may never use it 
                    // like asyncWait which will be GC'd, the losers in creating the asyncWait will also be GC'd 
                    System.Threading.Interlocked.CompareExchange(ref this.asyncWait, new System.Threading.ManualResetEvent(this.IsCompleted), null);
 
                    // multi-thread condition
                    // 1) thread 1 returned IAsyncResult and !IsCompleted so AsyncWaitHandle.WaitOne()
                    // 2) thread 2 signals complete, however thread 1 has retrieved this.completed but not assigned asyncWait
                    if (this.IsCompleted) 
                    {   // yes, Set may be called multiple times - but user would have to assume ManualResetEvent and call Reset
                        this.asyncWait.Set(); 
                    } 
                }
 
                return this.asyncWait;
            }
        }
 
        /// did the result complete synchronously?
        public bool CompletedSynchronously 
        { 
            get { return this.completedSynchronously; }
            internal set { this.completedSynchronously = value; } 
        }

        /// is the result complete?
        public bool IsCompleted 
        {
            get { return this.completed; } 
            internal set { this.completed = value; } 
        }
 
        #endregion

        /// first exception that happened
        internal Exception Failure 
        {
            get { return this.failure; } 
        } 

        ///  
        /// common handler for EndExecuteBatch & EndSaveChanges
        /// 
        /// derived type of the AsyncResult
        /// source object of async request 
        /// async method name on source object
        /// the asyncResult being ended 
        /// data service response for batch 
        internal static T EndExecute(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult
        { 
            Util.CheckArgumentNull(asyncResult, "asyncResult");

            T result = (asyncResult as T);
            if ((null == result) || (source != result.Source) || (result.Method != method)) 
            {
                throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); 
            } 

            Debug.Assert((result.CompletedSynchronously && result.IsCompleted) || !result.CompletedSynchronously, "CompletedSynchronously && !IsCompleted"); 

            if (!result.IsCompleted)
            {   // if the user doesn't want to wait forever, they should explictly wait on the handle with a timeout
                result.AsyncWaitHandle.WaitOne(); 

                Debug.Assert(result.IsCompleted, "not completed after waiting"); 
            } 

            if (System.Threading.Interlocked.Exchange(ref result.done, 1) != 0) 
            {
                throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult");
            }
 
            if (null != result.failure)
            { 
                throw Error.InvalidOperation(Strings.Context_SaveChangesError, result.failure); 
            }
 
            return result;
        }

        /// Set the AsyncWait and invoke the user callback. 
        internal void HandleCompleted()
        { 
            if (Util.DoNotHandleException(this.failure)) 
            {
                return; 
            }

            if (this.IsCompleted && (System.Threading.Interlocked.Exchange(ref this.userNotified, 1) == 0))
            { 
                try
                { 
                    this.CompletedRequest(); 
                }
                catch (Exception ex) 
                {
                    if (this.HandleFailure(ex))
                    {
                        throw; 
                    }
                } 
 
                if (null != this.asyncWait)
                { 
                    this.asyncWait.Set();
                }

                if (null != this.userCallback) 
                {   // any exception thrown by user should be "unhandled"
                    this.userCallback(this); 
                } 
            }
        } 

        /// Cache the exception that happened on the background thread for the caller of EndSaveChanges.
        /// exception object from background thread
        /// true if the exception (like StackOverflow or ThreadAbort) should be rethrown 
        internal bool HandleFailure(Exception e)
        { 
            System.Threading.Interlocked.CompareExchange(ref this.failure, e, null); 
            this.completed = true;
            return Util.DoNotHandleException(e); 
        }

        /// invoked for derived classes to cleanup before callback is invoked
        protected abstract void CompletedRequest(); 
    }
} 

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