欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何實現(xiàn)C#異步的APM模式異步程序開發(fā)

如何實現(xiàn)C#異步的APM模式異步程序開發(fā)?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供衡南網(wǎng)站建設(shè)、衡南做網(wǎng)站、衡南網(wǎng)站設(shè)計、衡南網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、衡南企業(yè)網(wǎng)站模板建站服務(wù),十余年衡南做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

C#已有10多年歷史,單從微軟2年一版的更新進(jìn)度來看活力異常旺盛,C#中的異步編程也經(jīng)歷了多個版本的演化,從今天起著手寫一個系列博文,記錄一下C#中的異步編程的發(fā)展歷程。

我是2004年接觸并使用C#的,那時C#版本為1.1,所以我們就從就那個時候談起。那時在大學(xué)里自己看書寫程序,所寫的程序大都是同步程序,最多啟動個線程........其實在C#1.1的時代已有完整的異步編程解決方案,那就是APM(異步編程模型)。如果還有不了解“同步程序、異步程序”的請自行百度哦。

APM異步編程模型最具代表性的特點是:一個異步功能由以Begin開頭、End開頭的兩個方法組成。Begin開頭的方法表示啟動異步功能的執(zhí)行,End開頭的方法表示等待異步功能執(zhí)行結(jié)束并返回執(zhí)行結(jié)果。下面是一個模擬的實現(xiàn)方式(后面將編寫標(biāo)準(zhǔn)的APM模型異步實現(xiàn)):

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)
            {                t
            hrow new Exception("調(diào)用EndWork前,需要先調(diào)用BeginWork");
            }            
            else
            {
                et.WaitOne();                
                return R;
            }

        } 
    }
        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();
        }

在上面的模擬APM模型中我們使用了 Thread、ManualResetEvent,如果你對多線程和ManualResetEvent不熟悉C#中使用異步編程不可避免的會涉及到多線程的知識,雖然微軟在Framework中做了很多封裝,但朋友們應(yīng)該掌握其本質(zhì)。

上面模擬的APM異步模型之所以簡單,是因為C#發(fā)展過程中引入了很多優(yōu)秀的語法規(guī)則。上例我們較多的使用了Lambda表達(dá)式,如果你不熟悉 匿名委托與lambda表達(dá)式可看我之前的Bolg《匿名委托與Lambda表達(dá)式》。上面做了如此多的廣告,下面我們來看一下標(biāo)準(zhǔn)的APM模型如何實現(xiàn)異步編程。

IAsyncResult接口

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

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

注意:模型示例1中的 ManualResetEvent 繼承自 WaitHandle
APM傳說實現(xiàn)方式
在了解了IAsyncResult接口后,我們來通過實現(xiàn) IAsyncResult 接口的方式完成對模擬示例的改寫工作,代碼如下:

    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;
        }
    }

示例代碼分析:

上面代碼中NewWorker的內(nèi)部類 WorkerAsyncResult 是關(guān)鍵點,它實現(xiàn)了 IAsyncResult 接口并由它來負(fù)責(zé)開啟新線程完成計算工作。

在WorkerAsyncResult中增加了 A、B兩個私有屬性來存儲用于計算的數(shù)值,一個對外可讀不可寫的屬性R,用于存儲WorkerAsyncResult內(nèi)部運算的結(jié)果。AsyncWaitHandle屬性由 ManualResetEvent 來充當(dāng),并在首次訪問時創(chuàng)建ManualResetEvent(但不釋放)。其他接口屬性正常實現(xiàn),沒有什么可說。

WorkerAsyncResult 中新增 static Count 方法,參數(shù) state 為調(diào)用Count方法的當(dāng)前WorkerAsyncResult對象。Count 方法在 WorkerAsyncResult 對象的新啟線程中運行,因此Thread.Sleep(1000)將阻塞新線程1秒中。然后設(shè)置當(dāng)前WorkerAsyncResult對象是否同步完成為false,異步完成狀態(tài)為true,釋放ManualResetEvent通知以便等待線程獲取通知進(jìn)入執(zhí)行狀態(tài),判斷是否有異步執(zhí)行結(jié)束回調(diào)委托,存在則回調(diào)之。

NewWorker 非常簡單,Num1、Num2兩個屬性為要計算的數(shù)值。BeginWork 創(chuàng)建WorkerAsyncResult對象、并將要計算的兩個數(shù)值Num1、Num2、userCallback回調(diào)委托、object 類型的 asyncState 傳入要創(chuàng)建的WorkerAsyncResult對象。經(jīng)過此步操作,WorkerAsyncResult對象獲取了運算所需的所有數(shù)據(jù)、運算完成后的回調(diào),并馬上啟動新線程進(jìn)行運算(執(zhí)行WorkerAsyncResult.Count方法)。

因為WorkerAsyncResult.Count執(zhí)行在新線程中,在該線程外部無法準(zhǔn)確獲知新線程的狀態(tài)。為了滿足外部線程與新線程同步的需求,在NewWorker中增加EndWork方法,參數(shù)類型為IAsyncResult。要調(diào)用EndWork方法應(yīng)傳入BeginWork 獲取的WorkerAsyncResult對象,EndWork方法獲取WorkerAsyncResult對象后,調(diào)用WorkerAsyncResult.AsyncWaitHandle.WaitOne()方法,等待獲取ManualResetEvent通知,在獲取到通知時運算線程已運算結(jié)束(線程并未結(jié)束),下一步獲取運算結(jié)果R并返回。

接下來是NewWorker調(diào)用程序,如下:

        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();
        }

如何實現(xiàn)C#異步的APM模式異步程序開發(fā)

下圖我簡單畫的程序調(diào)用過程,有助于各位朋友理解:

如何實現(xiàn)C#異步的APM模式異步程序開發(fā)

標(biāo)準(zhǔn)的APM模型異步編程,對應(yīng)開發(fā)人員來說過于復(fù)雜。因此通過實現(xiàn) IAsyncResult 接口進(jìn)行異步編程,就是傳說中的中看不中用(罪過罪過.....)。

Delegate異步編程(APM 標(biāo)準(zhǔn)實現(xiàn))

C#中委托天生支持異步調(diào)用(APM模型),任何委托對象后"."就會發(fā)現(xiàn)BeginInvoke、EndInvoke、Invoke三個方法。BeginInvoke為異步方式調(diào)用委托、EndInvoke等待委托的異步調(diào)用結(jié)束、Invoke同步方式調(diào)用委托。因此上面的標(biāo)準(zhǔn)APM實例,可借助  delegate 進(jìn)行如下簡化。

上面NewWorker使用委托方式改寫如下:


    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;
        }
    }

調(diào)用程序:

        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();
        }

上面的使用委托進(jìn)行APM異步編程,比實現(xiàn) IAsyncResult 接口的方式精簡太多、更易理解使用。因此這里建議朋友們 delegate 異步調(diào)用模型應(yīng)該掌握起來,而通過實現(xiàn) IAsyncResult 

關(guān)于如何實現(xiàn)C#異步的APM模式異步程序開發(fā)問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

文章題目:如何實現(xiàn)C#異步的APM模式異步程序開發(fā)
路徑分享:http://aaarwkj.com/article30/pcdeso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、域名注冊、網(wǎng)站改版、靜態(tài)網(wǎng)站、網(wǎng)站建設(shè)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)
九九热视频这里是精品| 成年人免费国产视频网站| 中文字幕一区二区三区久久| 久久人人97超碰人人爱一久久精品 | 久久视频在线播放视频| 欧美日韩国产另类在线视频| 中文字幕五月婷婷免费| 日韩在线视频观看一区二区三区| 日韩欧美亚洲一区二区三区| 国产精品免费看片网站| 欧美亚洲清纯唯美另类| 日韩av一区二区国产| 久久日韩制服丝袜人妻| 久久婷婷精品国产亚洲av| 91亚色在线免费观看| av在线日韩国产精品| 亚欧乱色熟女一区二区三区| 真人国产一级美女免费视频| 国产一边打电话一边操| 门国产av一区二区三区| 欧美精品一区影片在线观看| 亚洲最大五月六月丁香婷婷| 禁区正片免费看完整国产 | 欧美日韩精品成人大片| 国产亚洲精品视频在线网 | av资源天堂第一区第二区第三区| 最新亚洲国产高清激情| 内射极品美女在线观看| 国产美女主播视频一区二区三区| 丰满人妻被猛烈进入中| 国产精品国产三级专区| av影片在线观看亚洲天堂| 日韩人妖视频在线观看| 国产中文字幕有码视频| 欧美亚洲综合日韩精品区| 最新国产激情福利网站| 国产精品高清国产三级av| 国产成人国产三级国产精品| 亚洲国产专区一区二区麻豆| 婷婷人妻中文字幕在线| 99热免费精品在线观看|