c#中異步編程

異步是現實生活中的不少現象的一種抽象。好比分工合做在不少時間段就是異步合做。異步中也通常要涉及委託方法。c#有3種模式的異步編程:異步模式,基於事件的異步模式,基於任務的異步模式(TAP).html

一.  FrameWork 4.0以前的線程世界    編程

    在.NET FrameWork 4.0以前,若是咱們使用線程。通常有如下幾種方式:c#

  • 使用System.Threading.Thread 類,調用實例方法Start()開啓一個新線程,調用Abort()方法來提早終止線程。
  • 使用System.Threading.ThreadPool類,調用靜態方法QueueUserWorkItem(),將方法放入線程池隊列,線程池來控制調用。
  • 使用BeginInvoke,EndInvoke,BeginRead,EnRead,BeginWrite,EndWrite等一系列的異步方法。
  • 使用System.ComponentModel.BackgroundWorker控件,調用實例方法RunWorkerAsync(),開啓一個新線程。 

二.  .Net 傳統異步編程概述 異步

  • 異步編程模型 (APM),在該模型中異步操做由一對 Begin/End 方法(如 FileStream.BeginRead 和 Stream.EndRead)表示。
  • 基於事件的異步模式 (EAP),在該模式中異步操做由名爲「操做名稱Async」和「操做名稱Completed」的方法/事件對(例如 WebClient.DownloadStringAsync 和 WebClient.DownloadStringCompleted)表示。 (EAP 是在 .NET Framework 2.0 版中引入的,在silverlight或者wpf變成中常常用到)。

三.  Task 的優勢以及功能   async

  • 在任務啓動後,能夠隨時以任務延續的形式註冊回調。
  • 經過使用 ContinueWhenAll 和 ContinueWhenAny 方法或者 WaitAll 方法或 WaitAny 方法,協調多個爲了響應 Begin_ 方法而執行的操做。
  • 在同一 Task 對象中封裝異步 I/O 綁定和計算綁定操做。
  • 監視 Task 對象的狀態。
  • 使用 TaskCompletionSource 將操做的狀態封送到 Task 對象。

 第一種 異步模式 異步編程

public class 異步調用
{
        static void Main()
        {
            Console.WriteLine("===== 異步調用 AsyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);
            //IAsyncResult: 異步操做接口(interface)
            //BeginInvoke: 委託(delegate)的一個異步方法的開始
            IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
            Console.WriteLine("繼續作別的事情。。。");
            //異步操做返回 EndInvoke方式會阻塞主線程 須要等待異步線程調用完畢 纔會執行
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }
}

 

public class 異步回調
{
        static void Main()
        {
            Console.WriteLine("===== 異步回調 AsyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);
            //異步操做接口(注意BeginInvoke方法的不一樣!)
            IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回調函數),"AsycState:OK");
            Console.WriteLine("繼續作別的事情。。。");
            Console.ReadKey();
        }
 
        static void 回調函數(IAsyncResult result)
        {     
             //result 是「加法類.Add()方法」的返回值
            //AsyncResult 是IAsyncResult接口的一個實現類,空間:System.Runtime.Remoting.Messaging
            //AsyncDelegate 屬性能夠強制轉換爲用戶定義的委託的實際類。
            AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
          //或者 AddHandler handler=result.AsyncState as AddHandler;
            Console.WriteLine(handler.EndInvoke(result));
            Console.WriteLine(result.AsyncState);
        }
}

利用lambda表達式簡單寫法 (這個很經常使用。必定要理解和學會。)函數

            // public delegate string TakesAWhileDelegate(int data1, int data2); 定義一個委託
            TakesAWhileDelegate dl = (a, b) => { return (a + b).ToString(); }; //委託 實例化
            dl.BeginInvoke(1, 12, result => {                     //回調方法 實例化
              string str=dl.EndInvoke(result);                    //EndInvoke方法取回結果
              Console.WriteLine("取到異步的結果了result={0}", str);
            }, null);

第二種 基於事件的異步模式網站

.net中不少類的方法都定義了同步和異步兩種模式,例如WebClient類,就定義了DownloadStringAsync基於事件的異步模式。.net

            WebClient wc = new WebClient();
            string strUI = "我是主線程中的元素";
            wc.Encoding = Encoding.UTF8;
            //首先實例化 Completed事件。 注意:能夠直接訪問UI線程中的元素
            // public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e);
            wc.DownloadStringCompleted += (sender1, e1) => {   //e1 存放結果
                Console.WriteLine(strUI);
                string str = e1.Result;
                Console.WriteLine(str);
            };
            wc.DownloadStringAsync(new Uri("http://www.baidu.com"));
            Console.WriteLine("繼續主線程,不會由於訪問網站而阻塞");

第三種 基於任務的異步模式(Task,await,async關鍵字)線程

 

        private void button21_Click(object sender, EventArgs e)
        {
            Console.WriteLine("主線程已經開始了");
            CallerWithAsync();  //調用基於任務的異步方法
            Console.WriteLine("主線程已經結束了");

        }
        //建立基於任務的異步方法
        private async void CallerWithAsync() 
        {
            //async(方法修飾符)和await必須成對出現。順序執行
            string result = await GetAsync("第1個"); //等待 方法執行結果 阻塞線程。編譯器把await關鍵字後的全部代碼放進ContinueWith方法的代碼塊中
            string result2 = await GetAsync("第2個");
            Console.WriteLine("任務第3");
        }
        //經過任務使同步方法異步化
        private Task<string> GetAsync(string name)
        { 
        return Task.Run<string>(() => {
                Thread.Sleep(2000);
                Console.WriteLine(name);
                return name; });
        }

  

 

 

 

  

 TASK的用法     請參考這篇文章 

異步編程新利器

相關文章
相關標籤/搜索