APM

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;


namespace ConsoleTest
{
    //Figure 2 AsyncResultNoResult 类
    internal class AsyncResultNoResult : IAsyncResult
    {
        // Fields set at construction which never change while   
        // operation is pending  
        private readonly AsyncCallback m_AsyncCallback;
        private readonly Object m_AsyncState;

        // Fields set at construction which do change after
        // operation completes
        private const Int32 c_StatePending = 0;
        private const Int32 c_StateCompletedSynchronously = 1;
        private const Int32 c_StateCompletedAsynchronously = 2;

        private Int32 m_CompletedState = c_StatePending;
        // Field that may or may not get set depending on usage
       
        private ManualResetEvent m_AsyncWaitHandle;
        // Fields set when operation completes
        private Exception m_exception;

        #region Implementation of IAsyncResult
        public Object AsyncState
        {
            get { return m_AsyncState; }
        }

        public Boolean CompletedSynchronously
        {
            get { return Thread.VolatileRead(ref m_CompletedState) == c_StateCompletedSynchronously; }
        }

        public WaitHandle AsyncWaitHandle
        {
            get
            {
                if (m_AsyncWaitHandle == null)
                {
                    Boolean done = IsCompleted;
                    ManualResetEvent mre = new ManualResetEvent(done);
                    if (Interlocked.CompareExchange(ref m_AsyncWaitHandle, mre, null) != null)
                    {
                        // Another thread created this object's event; dispose
                        // the event we just created
                        mre.Close();
                    }
                    else
                    {
                        if (!done && IsCompleted)
                        {
                            // If the operation wasn't done when we created
                            // the event but now it is done, set the event
                            m_AsyncWaitHandle.Set();
                        }
                    }
                }
                return m_AsyncWaitHandle;
            }
        }

        public Boolean IsCompleted
        {
            get { return Thread.VolatileRead(ref m_CompletedState) != c_StatePending; }
        }
        #endregion

        public AsyncResultNoResult(AsyncCallback asyncCallback, Object state)
        {
            m_AsyncCallback = asyncCallback;
            m_AsyncState = state;
        }

        public void SetAsCompleted(Exception exception, Boolean completedSynchronously)
        {
            // Passing null for exception means no error occurred.
            // This is the common case
            m_exception = exception;
            // The m_CompletedState field MUST be set prior calling the callback
            Int32 prevState = Interlocked.Exchange(ref m_CompletedState, completedSynchronously ? c_StateCompletedSynchronously : c_StateCompletedAsynchronously);
            if (prevState != c_StatePending)
            {
                throw new InvalidOperationException("You can set a result only once");
            }
            // If the event exists, set it     
            if (m_AsyncWaitHandle != null)
            {
                m_AsyncWaitHandle.Set();
            }
            // If a callback method was set, call it     
            if (m_AsyncCallback != null)
            {
                m_AsyncCallback(this);
            }
        }

        public void EndInvoke()
        {
            // This method assumes that only 1 thread calls EndInvoke
            // for this object
            if (!IsCompleted)
            {
                // If the operation isn't done, wait for it
                AsyncWaitHandle.WaitOne();
                AsyncWaitHandle.Close();
                m_AsyncWaitHandle = null;
                // Allow early GC
            }
            // Operation is done: if an exception occured, throw it
            if (m_exception != null) throw m_exception;
        }


    }

    //--------------------------------------------------------------------------------

    //Figure 3 带返回值的 AsyncResult
    internal class AsyncResult<TResult> : AsyncResultNoResult
    {
        // Field set when operation completes
        private TResult m_result = default(TResult);
        public AsyncResult(AsyncCallback asyncCallback, Object state)
            :base(asyncCallback, state)
        {
        }
        public void SetAsCompleted(TResult result, Boolean completedSynchronously)
        {
            // Save the asynchronous operation's result
            m_result = result;
            // Tell the base class that the operation completed
            // sucessfully (no exception)
            base.SetAsCompleted(null, completedSynchronously);
        }
        new public TResult EndInvoke()
        {
            base.EndInvoke();           // Wait until operation has completed
            return m_result;            // Return the result (if above didn't throw)
        }
    }

    //--------------------------------------------------------------------------------

    //Figure 4 LongTask 模拟异步 I/O
    internal sealed class LongTask
    {
        private Int32 m_ms;
        // Milliseconds;
        public LongTask(Int32 seconds)
        {
            m_ms = seconds * 1000;
        }
        // Synchronous version of time-consuming method
        public DateTime DoTask()
        {
            Thread.Sleep(m_ms);     // Simulate time-consuming task
            return DateTime.Now;    // Indicate when task completed
        }
        // Asynchronous version of time-consuming method (Begin part)
        public IAsyncResult BeginDoTask(AsyncCallback callback, Object state)
        {
            // Create IAsyncResult object identifying the
            // asynchronous operation
            AsyncResult<DateTime> ar = new AsyncResult<DateTime>(callback, state);

            // Use a thread pool thread to perform the operation
            ThreadPool.QueueUserWorkItem(DoTaskHelper, ar);
            return ar;            // Return the IAsyncResult to the caller
        }
        // Asynchronous version of time-consuming method (End part)
        public DateTime EndDoTask(IAsyncResult asyncResult)
        {
            // We know that the IAsyncResult is really an      
            // AsyncResult<DateTime> object
            AsyncResult<DateTime> ar = (AsyncResult<DateTime>)asyncResult;
            // Wait for operation to complete, then return result or
            // throw exception
            return ar.EndInvoke();
        }
        // Asynchronous version of time-consuming method (private part   
        // to set completion result/exception)
        private void DoTaskHelper(Object asyncResult)
        {
            // We know that it's really an AsyncResult<DateTime> object
            AsyncResult<DateTime> ar = (AsyncResult<DateTime>)asyncResult;
            try
            {
                // Perform the operation; if sucessful set the result
                DateTime dt = DoTask();
                ar.SetAsCompleted(dt, false);
            }
            catch (Exception e)
            {
                // If operation fails, set the exception
                ar.SetAsCompleted(e, false);
            }
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值