1. 程式人生 > >C# 異步編程學習(一)

C# 異步編程學習(一)

apm 結果 mic public b- num row worker inf

異步 編程 可在 等待 某個 任務 完成時, 避免 線程 的 占用, 但要 想 正確地 實現 編程, 仍然 十分 傷腦筋。

. NET Framework 中, 有三種 不同 的 模型 來 簡化 異步 編程。

.NET 1. x 中的 BeginFoo/ EndFoo 方法, 使用 IAsyncResult 和 AsyncCallback 來 傳播 結果。

.NET 2. 0 中 基於 事件 的 異步 模式, 使用 BackgroundWorker 和 WebClient 實現。

.NET 4 引入 並由. NET 4. 5 擴展 的 任務 並行 庫( TPL)。

(一)APM(異步編程模型)C#版本為1.1

APM異步編程模型最具代表性的特點是:一個異步功能由以Begin開頭、End開頭的兩個方法組成。Begin開頭的方法表示啟動異步功能的執行,End開頭的方法表示等待異步功能執行結束並返回執行結果;

模擬實現:

技術分享圖片
public class Worker
    {
        public int A { get; set; }
        public int B { get; set; }
        private int R { get; set; }
        ManualResetEvent et;
        public void BeginWork(Action action)
        {
            et 
= new ManualResetEvent(false); new Thread(() => { R = A + B; Thread.Sleep(1000); et.Set(); if(null != action) { action(); } }).Start(); }
public int EndWork() { if(null == et) { throw new Exception("調用EndWork前,需要先調用BeginWork"); } else { et.WaitOne(); return R; } } }
View Code

調用代碼:

技術分享圖片
 static void Main(string[] args)
        {
           Worker w = new Worker();
            w.BeginWork(()=> {
                Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
                    w.EndWork());
            });
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
View Code

標準的APM模型如何實現異步編程:

IAsyncResult接口

IAsyncResult接口定義了異步功能的狀態,該接口具體屬性及含義如下:

技術分享圖片
 //     表示異步操作的狀態。
    [ComVisible(true)]
    public interface IAsyncResult
    {
        //
        // 摘要:
        //     獲取一個值,該值指示異步操作是否已完成。
        //
        // 返回結果:
        //     如果操作已完成,則為 true;否則為 false。
        bool IsCompleted { get; }
        //
        // 摘要:
        //     獲取用於等待異步操作完成的 System.Threading.WaitHandle。
        //
        // 返回結果:
        //     用於等待異步操作完成的 System.Threading.WaitHandle。
        WaitHandle AsyncWaitHandle { get; }
        //
        // 摘要:
        //     獲取一個用戶定義的對象,該對象限定或包含有關異步操作的信息。
        //
        // 返回結果:
        //     一個用戶定義的對象,限定或包含有關異步操作的信息。
        object AsyncState { get; }
        //
        // 摘要:
        //     獲取一個值,該值指示異步操作是否同步完成。
        //
        // 返回結果:
        //     如果異步操作同步完成,則為 true;否則為 false。
        bool CompletedSynchronously { get; }
    }
View Code

接口的實現:

技術分享圖片
public class NewWorker
    {
        public class WorkerAsyncResult : IAsyncResult
        {
            AsyncCallback callback;
            public WorkerAsyncResult(int a,int b, AsyncCallback callback, object asyncState) {
                A = a;
                B = b;
                state = asyncState;
                this.callback = callback;
                new Thread(Count).Start(this);
            }
            public int A { get; set; }
            public int B { get; set; }

            public int R { get; private set; }

            private object state;
            public object AsyncState
            {
                get
                {
                    return state;
                }
            }
            private ManualResetEvent waitHandle;
            public WaitHandle AsyncWaitHandle
            {
                get
                {
                    if (null == waitHandle)
                    {
                        waitHandle = new ManualResetEvent(false);
                    }
                    return waitHandle;
                }
            }
            private bool completedSynchronously;
            public bool CompletedSynchronously
            {
                get
                {
                    return completedSynchronously;
                }
            }
            private bool isCompleted;
            public bool IsCompleted
            {
                get
                {
                    return isCompleted;
                }
            }
            private static void Count(object state)
            {
                var result = state as WorkerAsyncResult;
                result.R = result.A + result.B;
                Thread.Sleep(1000);
                result.completedSynchronously = false;
                result.isCompleted = true;
                ((ManualResetEvent)result.AsyncWaitHandle).Set();
                if (result.callback != null)
                {
                    result.callback(result);
                }
            }
        }
        public int Num1 { get; set; }
        public int Num2 { get; set; }

        public IAsyncResult BeginWork(AsyncCallback userCallback, object asyncState)
        {
            IAsyncResult result = new WorkerAsyncResult(Num1,Num2,userCallback, asyncState);
            return result;
        }

        public int EndWork(IAsyncResult result)
        {
            WorkerAsyncResult r = result as WorkerAsyncResult;
            r.AsyncWaitHandle.WaitOne();
            return r.R;
        }
    }
View Code

調用:

技術分享圖片
static void Main(string[] args)
        {
            NewWorker w2 = new NewWorker();
            w2.Num1 = 10;
            w2.Num2 = 12;
            IAsyncResult r = null;
            r = w2.BeginWork((obj) => {
            Console.WriteLine("Thread Id:{0},Count:{1}",Thread.CurrentThread.ManagedThreadId,
            w2.EndWork(r));
            }, null);
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
View Code

Delegate異步編程(APM 標準實現)

技術分享圖片
public class NewWorker2
    {
        Func<int, int, int> action;
        public NewWorker2()
        {
            action = new Func<int, int, int>(Work);
        }
        public IAsyncResult BeginWork(AsyncCallback callback, object state)
        {
            dynamic obj = state;
            return action.BeginInvoke(obj.A, obj.B, callback, this);
        }

        public int EndWork(IAsyncResult asyncResult)
        {
            try
            {
                return action.EndInvoke(asyncResult);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private int Work(int a, int b)
        {
            Thread.Sleep(1000);
            return a + b;
        }
    }
View Code 技術分享圖片
 static void Main(string[] args)
        {
            NewWorker2 w2 = new NewWorker2();
            IAsyncResult r = null;
            r = w2.BeginWork((obj) =>
            {
                Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
                    w2.EndWork(r));
            }, new { A = 10, B = 11 });
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);

            Console.ReadLine();
        }
View Code

學習網站:https://blog.csdn.net/nginxs/article/details/77917172

C# 異步編程學習(一)