C# 同步異步的區別


程序是為完成特定任務,用戶某種語言編寫的一組指令的集合,它是一段靜態的代碼,而進程是程序的一次執行的過程,是系統進行調度和資源分配的一個獨立的單元。

 

先弄清楚進程和線程的區別:

【進程的本質】程序的一次執行的過程,是系統進行調度和資源分配的一個獨立的單元。

【線程的本質】
  線程不是一個計算機硬件的功能,而是操作系統提供的一種邏輯功能,線程本質上是進程中一段並發運行的代碼,所以線程需要操作系統投入CPU資源來運行和調度,是比進程更小的執行單位,一個進程在執行的過程中,可以產生多個線程,形成多條執行線索。

c#中同步操作和異步操作的區別:

百度資料:找到了這樣一句話:

同步方法調用在程序繼續執行之前需要等待同步方法執行完畢返回結果
異步方法則在被調用之后立即返回以便程序在被調用方法完成其任務的同時執行其它操作。

同步:比如有三個程序要執行,必須第一個程序被觸發,執行結束了嗎,才輪到其他程序執行。

異步:所有程序的執行不需要同步,可以多個觸發,互相獨立的執行相應的指令。

很繞口,認真讀幾遍,便會發現,其實概念很清楚:自己簡單的理解是多個程序同步執行和不同步執行的區別,

在C#中,.NET框架基類庫中有好幾種類都可以提供同步和異步的方法調用。
因為同步方法調用會導致程序流程中途等待,所以采用同步方法的情況下往往會導致程序執行的延遲
相比來說,在某些條件下選擇異步方法調用就可能更好一些
例如,有的時候程序需要給多個Web服務發出請求,還有遠程處理信道(HTTP、TCP)和代理,這時就最好采用異步方法。

還是看代碼:

以下轉載》》click here

通過代碼定義一個委托和下面三個示例將要調用的方法:


    public delegate int AddHandler(int a,int b);
    public class 加法類
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("開始計算:" + a + "+" + b);
            Thread.Sleep(3000); //模擬該方法運行三秒
            Console.WriteLine("計算完成!");
            return a + b;
        }
    }
同步調用

委托的Invoke方法用來進行同步調用。同步調用也可以叫阻塞調用,它將阻塞當前線程,然后執行調用,調用完畢后再繼續向下進行。

public class 同步調用
{
        static void Main()
        {
            Console.WriteLine("===== 同步調用 SyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);
            int result = handler.Invoke(1, 2);

            Console.WriteLine("繼續做別的事情。。。");

            Console.WriteLine(result);
            Console.ReadKey();
        }
        
}
同步調用會阻塞線程,如果是要調用一項繁重的工作(如大量IO操作),可能會讓程序停頓很長時間,造成糟糕的用戶體驗,這時候異步調用就很有必要了。

異步調用

異步調用不阻塞線程,而是把調用塞到線程池中,程序主線程或UI線程可以繼續執行。
委托的異步調用通過BeginInvoke和EndInvoke來實現。

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("繼續做別的事情。。。");

            //異步操作返回
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }
        
}
可以看到,主線程並沒有等待,而是直接向下運行了。
但是問題依然存在,當主線程運行到EndInvoke時,如果這時調用沒有結束(這種情況很可能出現),這時為了等待調用結果,線程依舊會被阻塞。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM