AsyncResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / AsyncResult.cs / 1 / AsyncResult.cs

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

namespace System.ServiceModel 
{
    using System.Threading; 
    using System.ServiceModel.Diagnostics; 
    using System.Diagnostics;
 

    abstract class AsyncResult : IAsyncResult
    {
#if DEBUG_EXPENSIVE 
        StackTrace endStack;
        StackTrace completeStack; 
#endif 
        AsyncCallback callback;
        object state; 
        bool completedSynchronously;
        bool endCalled;
        Exception exception;
        bool isCompleted; 
        ManualResetEvent manualResetEvent;
        object thisLock; 
        ServiceModelActivity callbackActivity = null; 

        protected AsyncResult(AsyncCallback callback, object state) 
        {
            this.callback = callback;
            this.state = state;
            this.thisLock = new object(); 
        }
 
        public object AsyncState 
        {
            get 
            {
                return state;
            }
        } 

        public WaitHandle AsyncWaitHandle 
        { 
            get
            { 
                if (manualResetEvent != null)
                {
                    return manualResetEvent;
                } 

                lock (ThisLock) 
                { 
                    if (manualResetEvent == null)
                    { 
                        manualResetEvent = new ManualResetEvent(isCompleted);
                    }
                }
 
                return manualResetEvent;
            } 
        } 

        public ServiceModelActivity CallbackActivity 
        {
            get { return this.callbackActivity; }
            set { this.callbackActivity = value; }
        } 

        public bool CompletedSynchronously 
        { 
            get
            { 
                return completedSynchronously;
            }
        }
 
        public bool HasCallback
        { 
            get 
            {
                return this.callback != null; 
            }
        }

        public bool IsCompleted 
        {
            get 
            { 
                return isCompleted;
            } 
        }

        object ThisLock
        { 
            get
            { 
                return this.thisLock; 
            }
        } 

        /// 
        /// Call this version of complete when your asynchronous operation is complete.  This will update the state
        /// of the operation and notify the callback. 
        /// 
        ///  
        protected void Complete(bool completedSynchronously) 
        {
            if (isCompleted) 
            {
                // It's a bug to call Complete twice.
                DiagnosticUtility.DebugAssert("AsyncResult complete called twice for the same operation.");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
 
#if DEBUG_EXPENSIVE 
            if (completeStack == null)
                completeStack = new StackTrace(); 
#endif

            this.completedSynchronously = completedSynchronously;
 
            if (completedSynchronously)
            { 
                // If we completedSynchronously, then there's no chance that the manualResetEvent was created so 
                // we don't need to worry about a race
                DiagnosticUtility.DebugAssert(this.manualResetEvent == null, "No ManualResetEvent should be created for a synchronous AsyncResult."); 
                this.isCompleted = true;
            }
            else
            { 
                lock (ThisLock)
                { 
                    this.isCompleted = true; 
                    if (this.manualResetEvent != null)
                    { 
                        this.manualResetEvent.Set();
                    }
                }
            } 

            if (callback != null) 
            { 
                try
                { 
                    using (this.CallbackActivity == null ? null : ServiceModelActivity.BoundOperation(this.CallbackActivity))
                    {
                        callback(this);
                    } 
                }
#pragma warning suppress 56500 // [....], transferring exception to another thread 
                catch (Exception e) 
                {
                    if (DiagnosticUtility.ShouldTraceWarning) 
                    {
                        System.ServiceModel.Diagnostics.TraceUtility.TraceEvent(TraceEventType.Warning,  System.ServiceModel.Diagnostics.TraceCode.AsyncCallbackThrewException, e, null);
                    }
 
                    if (DiagnosticUtility.IsFatal(e)) throw;
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(SR.GetString(SR.AsyncCallbackException), e); 
                }
            } 
        }

        /// 
        /// Call this version of complete if you raise an exception during processing.  In addition to notifying 
        /// the callback, it will capture the exception and store it to be thrown during AsyncResult.End.
        ///  
        ///  
        protected void Complete(bool completedSynchronously, Exception exception)
        { 
            this.exception = exception;
            Complete(completedSynchronously);
        }
 
        /// 
        /// End should be called when the End function for the asynchronous operation is complete.  It 
        /// ensures the asynchronous operation is complete, and does some common validation. 
        /// 
        ///  
        protected static TAsyncResult End(IAsyncResult result)
            where TAsyncResult : AsyncResult
        {
            if (result == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result"); 
            } 

            TAsyncResult asyncResult = result as TAsyncResult; 

            if (asyncResult == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult)); 
            }
 
            if (asyncResult.endCalled) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AsyncObjectAlreadyEnded))); 
            }

#if DEBUG_EXPENSIVE
            if (asyncResult.endStack == null) 
                asyncResult.endStack = new StackTrace();
#endif 
 
            asyncResult.endCalled = true;
 
            if (!asyncResult.isCompleted)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
            } 

            if (asyncResult.manualResetEvent != null) 
            { 
                asyncResult.manualResetEvent.Close();
            } 

            if (asyncResult.exception != null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(asyncResult.exception); 
            }
 
            return asyncResult; 
        }
    } 
}

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


                        

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