国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

閱讀《LEARNING HARD C#學習筆記》知識點總結與摘要五

2019-11-17 02:23:08
字體:
來源:轉載
供稿:網友

閱讀《LEARNING HARD C#學習筆記》知識點總結與摘要五

本篇文章主要是總結異步編程的知識點,也是本系列的最后一篇文章,每一個知識點我都有寫出示例代碼,方便大家理解,若發現有誤或不足之處還請指出,由于書中作者對此知識點講解過于簡單,所以在寫這篇文章時本人參考與學習了網上許多大牛們的經驗,在此感謝那些愿意分享的人們,謝謝!

二十三.異步編程

APM(異步編程模型):若類實現了返回類型為IAsyncResult接口的BeginXXX方法和EndXXX方法,則表明該類支持異步編程模型。如:委托類型定義了BeginInvoke與EndInvoke方法,所以所有的委托類型都實現了異步編程模型;

調用方法代碼如下(以讀取文件內容為例):

第一種方法(先調用BeginRead方法,再調用EndRead方法):

FileStream fs = new FileStream("文件路徑", FileMode.Open);            byte[] data = new byte[fs.Length];            IAsyncResult result = fs.BeginRead(data, 0, data.Length,null, null);            fs.EndRead(result);            fs.Close();            fs.Dispose();            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();            string readContent = UTF8.GetString(data);            Console.WriteLine(readContent);            Console.Read();

注意:調用EndRead方法時,會阻塞當前調用的線程,直到處理完成,若在UI線程中調用,將會出現UI假死現象;

第二種方法(先調用BeginRead方法,再通過IAsyncResult. AsyncWaitHandle得到WaitHandle對象,然后執行WaitHandle. WaitOne方法來等待異步執行完成,最后執行EndRead方法):

FileStream fs = new FileStream("文件路徑", FileMode.Open);            byte[] data = new byte[fs.Length];            IAsyncResult result = fs.BeginRead(data, 0, data.Length, null, null);            WaitHandle readWait=result.AsyncWaitHandle;            readWait.WaitOne();fs.EndRead(result);            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();            string readContent = UTF8.GetString(data);            Console.WriteLine(readContent);            Console.Read();

注意:調用WaitOne方法時,會阻塞當前調用的線程,直到處理完成,若在UI線程中調用,將會出現UI假死現象;

第三種方法(先調用BeginRead方法,再循環判斷IAsyncResult. IsCompleted,最后執行EndRead方法):

FileStream fs = new FileStream("文件路徑", FileMode.Open);            byte[] data = new byte[fs.Length];            IAsyncResult result = fs.BeginRead(data, 0, data.Length, null, null);            while(!result.IsCompleted)            {                Thread.Sleep(1000);            }            fs.EndRead(result);            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();            string readContent = UTF8.GetString(data);            Console.WriteLine(readContent);            Console.Read();

注意:循環判斷IsComplete方法時,會阻塞當前調用的線程,直到處理完成[即:IsCompleted=true],若在UI線程中循環判斷,將會出現UI假死現象;

第四種方法(先定義回調方法,然后再調用BeginRead方法,調用時傳入異步回調方法委托實例及相關數據):

FileStream fs = new FileStream("文件路徑", FileMode.Open);            byte[] data = new byte[fs.Length];            IAsyncResult result = fs.BeginRead(data, 0, data.Length, new AsyncCallback(ReadCallback), data);            Console.Read();//回調方法static void ReadCallback(IAsyncResult ar)        {            WaitHandle readWait = ar.AsyncWaitHandle;            byte[] data =( byte[])ar.AsyncState;            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();            string readContent = UTF8.GetString(data);            Console.WriteLine(readContent);        }

說明:第四種由于采用異步委托方法獲取得結果,所以不會阻塞調用線程,也就不會出現UI假死現象,當然前面三種方法也可以將耗時邏輯(等待及獲取結果)放在方法中,然后在執行時開啟新線程,這樣可以達到與第四種相同的方法,但個人建議若在UI主線程中實現異步調用,優先考慮采用第四種方法;

EAP(基于事件的異步模式):實現了EAP的類具有一個或多個以Async為后綴的方法,以及對應的Completed事件,并支持異步方法的取消與進度報告。

EAP通過事件、AsyncOperationManager類和AsyncOperation類兩個幫助器類實現如下功能:

1) 異步執行耗時的任務。

2) 獲得進度報告和增量結果。

3) 支持耗時任務的取消。

4) 獲得任務的結果值或異常信息。

5) 更復雜:支持同時執行多個異步操作、進度報告、增量結果、取消操作、返回結果值或異常信息。

對于相對簡單的多線程應用程序,BackgroundWorker組件提供了一個簡單的解決方案。對于更復雜的異步應用程序,可以考慮實現一個符合基于事件的異步模式的類。

可參見這篇博文:http://m.survivalescaperooms.com/heyuquan/archive/2013/04/01/2993085.html

以下是BackgroundWorker組件在控制臺程序中的使用方法:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Consoleapplication1{    class PRogram    {        static int Main(string[] args)        {            Console.Write("Main Thread ID:{0}/n", System.Threading.Thread.CurrentThread.ManagedThreadId);            int workTimes = 100;            BackgroundWorker bgWorker = new BackgroundWorker();            bgWorker.WorkerSupportsCancellation = true;//設置支持異步取消            bgWorker.WorkerReportsProgress = true;//設置支持報告進度            bgWorker.DoWork += bgWorker_DoWork;            bgWorker.ProgressChanged += bgWorker_ProgressChanged;            bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;            bgWorker.RunWorkerAsync(workTimes);//啟動異步執行            string input = Console.ReadLine();            if (input == "c" && bgWorker.IsBusy)            {                bgWorker.CancelAsync();            }            Console.Read();            return 0;        }        static void bgWorker_DoWork(object sender, DoWorkEventArgs e)        {            //在新線程中處理該方法            BackgroundWorker bgWorker = sender as BackgroundWorker;            int workTimes = Convert.ToInt32(e.Argument);            for(int i = 0; i <= workTimes;i++ )            {                if (bgWorker.CancellationPending) //如果取消了                {                   e.Cancel = true;                   Console.Write("ThreadID:{0}-->Cancel!/n", System.Threading.Thread.CurrentThread.ManagedThreadId);                    break;                }                else                {                    Console.Write("Thread ID:{0}-->WorkTimes:{1}/n", System.Threading.Thread.CurrentThread.ManagedThreadId, i);                    bgWorker.ReportProgress(i);//投告進度,引發ProgressChanged事件                    System.Threading.Thread.Sleep(1000);                }            }        }        static void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)        {            //當進度改變時在新線程中調用該方法,可直接操作控件            Console.Write("Thread ID:{0}-->Progress:{1}/n", System.Threading.Thread.CurrentThread.ManagedThreadId, e.ProgressPercentage);        }        static void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            //當DoWork方法處理完成后(不論是否為取消)在新線程中調用此方法            Console.Write("Thread ID:{0}-->Completed!", System.Threading.Thread.CurrentThread.ManagedThreadId);        }    }}

TAP(基于任務的異步模式):一般使用Task類來實現基于任務的異步模式編程,實現步驟如下:

  1. 通過調用Task類指定的構造函數來實例化Task對象,如:Task task = new Task(Action委托實例,CancellationToken實例);注意:Task類有許多重載的構造函數,可依據實際情況進行調用
  2. 調用Task實例對象的Start方法啟動異步執行構造函數參數中Action委托實例所引用的方法,如:task.Start()

可參見這篇博文:http://m.survivalescaperooms.com/heyuquan/archive/2013/04/18/Task-based-Asynchronous-Pattern.html

具體的使用代碼示例如下(為了讓新手也能看懂,所以此處我采用標準的委托實例方法來寫,大家可以使用Lambda表達式來寫,那樣代碼量就會精簡一些):

using System;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form4 : Form    {        CancellationTokenSource cts = new CancellationTokenSource(); //用于發出與接收任務取消信息        public Form4()        {            InitializeComponent();        }        private void Form4_Load(object sender, EventArgs e)        {            TestTAP();        }        private void TestTAP()        {            WriteMsg(string.Format( "Main Thread ID:{0}", Thread.CurrentThread.ManagedThreadId));            SynchronizationContext syncContext = SynchronizationContext.Current; //獲取當前同步上下文,用于在異步中可操作UI上的控件等            Task task = new Task(new Action<object>(TAPAsyncMethod), syncContext);            task.Start();        }        private void TAPAsyncMethod(o
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武清区| 乌恰县| 德清县| 阳曲县| 梧州市| 航空| 泽普县| 永吉县| 读书| 兰西县| 洪湖市| 延川县| 凉城县| 辽宁省| 五寨县| 宜宾县| 都昌县| 华阴市| 花垣县| 临颍县| 凌海市| 大悟县| 江城| 得荣县| 和静县| 芮城县| 图们市| 台南市| 东海县| 昌乐县| 梁山县| 安化县| 兰考县| 安福县| 大洼县| 饶平县| 新乐市| 招远市| 都匀市| 聂荣县| 乳源|