C#同步和非同步呼叫

來源:互聯網
上載者:User

標籤:

這篇文章僅當總結之用,參考了很多前輩們的文章,加上了點點自己的理解

C#的同步和非同步線程是依靠委託來完成,主要需要用到委託的Invoke方法,BeginInvoke和EndInvoke方法

所謂同步線就是阻塞當前線程來完成調用的方法,然後才繼續調用當前線程的後面的操作,實際上都是在同一個線程中執行,效率不高。需要用到Invoke方法

非同步線程不阻塞當前線程,而是把需要調用的方法加入線程池中,來同步執行,即同一時間兩個及其以上的線程共同都在執行,效率很高。需要用到BeginInvoke和EndInvoke方法

具體請看下面的源碼和注釋(PS:絕大多數總結都在注釋當中了)

using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Runtime.Remoting.Messaging;using System.Text;using System.Threading;using System.Threading.Tasks;namespace AsyncRe{    class Program    {        static void Main(string[] args)        {            ImportantFun it=new ImportantFun();            //依次示範同步調用  不完全非同步呼叫  全非同步呼叫            it.Sync();            it.TerribleAsync();            it.Async();        }    }     //定義一個委託類型    public delegate int AddHandler(int x, int y);    /// <summary>    /// 示範同步調用和非同步呼叫    /// </summary>    class ImportantFun    {        //被調用的方法        private int Add(int x, int y)        {            //用於顯示當前方法所在的線程            Console.WriteLine("Add is running on thread"+Thread.CurrentThread.ManagedThreadId);            //線程停滯6s            Thread.Sleep(6000);            return x + y;        }               /// <summary>        /// 同步調用Add        /// </summary>       public void Sync()        {            Console.WriteLine("*********示範同步調用********");            //列印當前方法所在的線程            Console.WriteLine("Sync is running on thread"+Thread.CurrentThread.ManagedThreadId);            AddHandler handler=new AddHandler(Add);            //Invoke用於同步調用            int Result = handler.Invoke(1, 2);            Console.WriteLine("Add is Compete");            Console.WriteLine("Result="+Result);            Console.ReadKey();        }        /// <summary>        /// 不完整的非同步呼叫,具體見下面注釋        /// </summary>        public void TerribleAsync()        {            Console.WriteLine("***********示範不完整非同步呼叫**********");            Console.WriteLine("TerribaleAsync is running on thread"+Thread.CurrentThread.ManagedThreadId);            AddHandler handler=new AddHandler(Add);            //非同步呼叫一般用委託的BegInvoke和EndInvoke搭配在一起完成            //BeginInvoke表示非同步呼叫開始 返回一個表示調用狀態的介面(IAsyncResult)            IAsyncResult iar = handler.BeginInvoke(1, 2, null, null);            //上面本該有4個參數,暫且把3,4號參數定為null            Console.WriteLine("TerribaleAsync is running on thread" + Thread.CurrentThread.ManagedThreadId);            Console.WriteLine(iar.ToString());            //EndInvoke表示非同步呼叫時的方法,參數是IAsyncResult類型            int result = handler.EndInvoke(iar);            Console.WriteLine(result);            Console.WriteLine("此種非同步呼叫的方法有缺陷,在EndInvoke後面的方法同樣被阻隔,只能保證Begin和End中間是非同步");            Console.ReadKey();            //此種非同步呼叫的方法有缺陷,在EndInvoke後面的方法同樣被阻隔,只能保證Begin和End中間是非同步            //解決辦法是利用BeginInvoke中的3號和4號參數,將EndInvoke列在回呼函數當中            //實際上就是為了避免EndInvoke出現在其他地方,利用BegingInvoke方法一次性調用它。見下面的方法        }        /// <summary>        /// 完整非同步呼叫 原理就是在beginInvoke中調用End        /// </summary>        public void Async()        {            Console.WriteLine("***********示範非同步呼叫**********");            Console.WriteLine("Async is running on thread"+Thread.CurrentThread.ManagedThreadId);            AddHandler handler=new AddHandler(Add);            //new AsyncCallback(Callback)回呼函數,非同步呼叫結束時,runtime會自動調用該函數           //"Async parameter is me"作為回調參數 可以通過Async.AsyncState擷取            handler.BeginInvoke(1, 2, new AsyncCallback(CallBack), "Async parameter is me");            //     上面                        一個委託,回呼函數       回調參數            Console.WriteLine("Async is running on thread "+Thread.CurrentThread.ManagedThreadId);            //利用這步的輸出結果可以驗證是否是全非同步。            Console.ReadKey();        }        /// <summary>        /// 回呼函數        /// </summary>        /// <param name="iar"></param>        private void CallBack(IAsyncResult iar)        {            Console.WriteLine("CallBack is running on thread"+Thread.CurrentThread.ManagedThreadId);            //前者是非同步作業的結果  後者代表過程中的所有            AsyncResult Ar = (AsyncResult) iar;                        //擷取原委派物件       注意強制轉換            AddHandler handler = (AddHandler) Ar.AsyncDelegate;            //結束委託調用 得到結果            int result = handler.EndInvoke(Ar);            //輸出上面的Begin中的第4個參數            Console.WriteLine("The Async calling parameter is "+Ar.AsyncState);           //輸出結果            Console.WriteLine("Result ="+result);                  }    }   }

從圖片可以看出 同步調用都是在一個線程當中

非同步呼叫時再其他線程當中進行,特別注意理解回呼函數

一切的操作主要需要用到Invoke方法,BeginInvoke,EndInvoke,深刻理解三個函數的意義和參數就能夠理解同步和非同步呼叫

希望對大家有用。

C#同步和非同步呼叫

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.