C#中異步和多線程的區別介紹
一、區別和聯系
異步和多線程有什麼區別?其實,異步是目的,而多線程是實現這個目的的方法。異步是說,A發起一個操作後(一般都是比較耗時的操作,如果不耗時的操作就沒有必要異步瞭),可以繼續自顧自的處理它自己的事兒,不用幹等著這個耗時操作返回。.Net中的這種異步編程模型,就簡化瞭多線程編程,我們甚至都不用去關心Thread類,就可以做一個異步操作出來。
異步有的時候用普通的線程,有的時候用系統的異步調用功能。有一些IO操作也是異步的,但是未必需要一個線程來運行。例如:硬件是有DMA功能的,在調用DMA傳輸數據的時候,CPU是不需要執行處理的,隻需要發起傳輸和等待傳輸結束即可。具體到.net平臺,比如Socket的BeginSend,如果是運行在Windows 2000以後的平臺,在底層就會調用異步的完成端口來發送。
.Net中的異步執行其實使用的是異步委托。異步委托將要執行的方法提交到.net的線程池,由線程池中的線程來執行異步方法。
二、適用范圍
- 當需要執行I/O操作時,使用異步操作更合適。I/O操作不僅包括瞭直接的文件、網絡的讀寫,還包括數據庫操作、Web Service、HttpRequest以及.net Remoting等跨進程的調用。
- 而線程的適用范圍則是那種需要長時間CPU運算的場合,例如耗時較長的圖形處理和算法執行。
三、異步的一個示例
大傢可能都知道,使用delegate可以“自動”使一個方法可以進行異步的調用。從直覺上來說,我覺得是由編譯器或者CLR使用瞭另外的線程來執行目標方法。到底是不是這樣呢??讓我們來用一段代碼證明一下吧。
delegate void AsyncFoo(int i); static void Main(string[] args) { PrintCurrThreadInfo("Main()"); for (int i = 0; i < 10; i++) { PostAsync(); } Console.ReadLine(); } ///<summary> /// 輸出當前線程的信息 ///</summary> ///<param name="name">方法名稱</param> static void PrintCurrThreadInfo(string name) { Console.WriteLine("Thread Id of " + name + " is: " + Thread.CurrentThread.ManagedThreadId + ", current thread is " + (Thread.CurrentThread.IsThreadPoolThread ? "" : "not ") + "thread pool thread."); } ///<summary> /// 投遞一個異步調用 ///</summary> static void PostAsync() { AsyncFoo caller = new AsyncFoo(Foo); caller.BeginInvoke(1000, new AsyncCallback(FooCallBack), caller); } ///<summary> /// 測試方法,Sleep一定時間 ///</summary> ///<param name="i">Sleep的時間</param> static void Foo(int i) { PrintCurrThreadInfo("Foo()"); Thread.Sleep(i); } static void FooCallBack(IAsyncResult ar) { PrintCurrThreadInfo("FooCallBack()"); AsyncFoo caller = (AsyncFoo)ar.AsyncState; caller.EndInvoke(ar); }
這段代碼代碼的輸出如下:
Thread Id of Main() is: 1, current thread is not thread pool thread. Thread Id of Foo() is: 3, current thread is thread pool thread. Thread Id of FooCallBack() is: 3, current thread is thread pool thread. Thread Id of Foo() is: 3, current thread is thread pool thread. Thread Id of Foo() is: 4, current thread is thread pool thread. Thread Id of Foo() is: 5, current thread is thread pool thread. Thread Id of FooCallBack() is: 3, current thread is thread pool thread. Thread Id of Foo() is: 3, current thread is thread pool thread. Thread Id of FooCallBack() is: 4, current thread is thread pool thread. Thread Id of Foo() is: 4, current thread is thread pool thread. Thread Id of Foo() is: 6, current thread is thread pool thread. Thread Id of FooCallBack() is: 5, current thread is thread pool thread. Thread Id of Foo() is: 5, current thread is thread pool thread. Thread Id of Foo() is: 7, current thread is thread pool thread. Thread Id of FooCallBack() is: 3, current thread is thread pool thread. Thread Id of Foo() is: 3, current thread is thread pool thread. Thread Id of FooCallBack() is: 4, current thread is thread pool thread. Thread Id of FooCallBack() is: 6, current thread is thread pool thread. Thread Id of FooCallBack() is: 5, current thread is thread pool thread. Thread Id of FooCallBack() is: 7, current thread is thread pool thread. Thread Id of FooCallBack() is: 3, current thread is thread pool thread.
從輸出可以看出,.net 使用 delegate 來“自動”生成的異步調用是使用瞭另外的線程(而且是線程池線程)。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持LevelAH。