亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中異步多線程的示例分析

發布時間:2022-03-04 11:12:02 來源:億速云 閱讀:136 作者:小新 欄目:開發技術

這篇文章主要介紹C#中異步多線程的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

進程、線程

1. 進程

首先了解,什么是線程? 即一個應用程序運行時,占用資源的綜合是一個進程。Windows 任務管理器里面可以看到,里面一個個都是在運行的進程。

C#中異步多線程的示例分析

2. 線程

線程是執行流的最小單位。線程其實是看不到的,其實也可以,例如 Windows 任務管理器:正在運行 272 個進程,272 個進程運行了 3909 個線程,也就是一個進程可以擁有多個線程。

C#中異步多線程的示例分析

分時、分片

現在有個怪相,CPU 實在太快了,內存顯卡其他硬件資源其實都跟不上 CPU 的速度,于是就產生了分片的概念。從微觀角度來講,以前電腦很多都是單核,一時刻只能執行一個線程,按照這個道理,為什么我們的計算機還可以同時運行許多個應用呢。但從宏觀來說是并發的,多個應用同時執行,我們既可以掃雷也可以完蜘蛛紙牌還可以聽音樂。這就是分片,分片會產生一個上下文,假設當前執行掃雷線程,下一個時刻執行蜘蛛紙牌線程,CPU 會將掃雷線程上下文保存起來,切換成蜘蛛紙牌線程,這樣進行來回調度,從宏觀來看是并發的。

這個補充一點額外知識,多 CPU 多核,本身就可以完成多個線程的計算,可以獨立工作。4核8線程,核就是物理的核,線程是虛擬的核,每個核可以進行分片做并發的。

同步、異步

我們開發人員口中常說的同步、異步,其實是對方法執行的描述。因為編程語言本身是沒有線程的,它只能去向操作系統申請線程,去執行代碼。

同步方法,代碼執行第一行到最后一行依次執行到結束,完成第一行之后進入下第二行直到最后一行,這就是同步,阻塞式的。

異步方法,不會等待當前行執行完成,就會進行下一行執行代碼,非阻塞式的。

異步、多線程

多線程,就是多個執行流,同時執行。在 C# 中多線程就是多個并發的 Thread 開啟多個線程處理任務,利用的可能是 CPU 的多核,也可能是單核 CPU 分片完成執行的任務。

異步,其實是硬件式的異步,其實這個不太好理解。這里就拿文件寫入來說

多線程情況,線程會一直從文件寫入開始到結束,都參與工作這件事,也就是 CPU 會處理寫文件操作,線程會一直等待 CPU 向磁盤寫入文件直到完成。

異步情況,線程會給 CPU 發個指令與文件流交個操作系統,線程就可以忙別的事情去了,也就是利用硬件的特性,發個指令讓操作系統完成文件寫入,線程去執行其他任務,等 CPU 寫完后發個指令回來,通知到線程。

有同學會問這個異步怎么寫,其實在程序中是寫不了這個的,這是操作系統底層的東西,在 WPF 里面就可以直接調用。 C# 中常說的異步多線程指的是 ThreadPool、Task ,都是基于 Thread 完成的,只是 C# 語言進行了封裝的。

異步多線程效率

說起異步很多人都知道,同步方法慢,異步多線程快,這個大家心里面都是這么認為的。但效率究竟提升了多少呢

我們看下面程序,定義一個普通方法 Sum 做些 CPU 密集型運算,然后在 Main 方法,分別同步與異步,執行 Sum 方法。即同樣的任務使用單線程(主線程)運行五次,再使用多線程開啟 5 個線程,分別執行。

public static void Sum(int f)
{
    Console.WriteLine($"第{f}次  start:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");
    decimal s = 0;
    for (int i = 0; i < 1000000000; i++)
    {
        s = s + i;
    }
    Console.WriteLine($"第{f}次  end:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");
}

static void Main(string[] args)
{
    Console.WriteLine($"同步 start:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");
    for (int i = 0; i < 5; i++)
    {
        Sum(i);
    }
    Console.WriteLine($"同步 end:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");

    Console.WriteLine();

    Console.WriteLine($"異步 start:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");
    for (int i = 0; i < 5; i++)
    {
        Action<int> action = Sum;
        action.BeginInvoke(i,null,null);
    }
    Console.WriteLine($"異步 end:{DateTime.Now.ToLongTimeString()},Thread:{Thread.CurrentThread.ManagedThreadId}");

    Console.ReadKey();
}

C#中異步多線程的示例分析

啟動程序,可以看到,同步方法1個線程執行了 2 分 40 秒,異步方法 5 個線程執行了 52 秒,很顯然異步方法快與同步方法四倍多。

C#中異步多線程的示例分析

說到這可能有的同學會發現,同步1個線程,異步5個線程,為什么效率不提升五倍呢,不是線性增長呢?其實,異步效率提升受限于資源限制、上下文切換成本

上面我們說過 CPU 的分時分片,即使單核也可以同時運行多個程序,那既要馬兒跑得快,又要馬兒不吃草,怎么可能呢,這就是上下文切換的管理成本。

資源限制,異步效率不高也可能資源不夠。如下,我們啟動資源管理器并啟動程序,可以看到同步時 CPU 使用的資源并不高執行但時間長,當多線程時 CPU 達到了 100% 但執行時間短,也就是一種資源換時間策略。

C#中異步多線程的示例分析

多線程無序性

因為計算機的分時分片,會使得多線程無序。即啟動無序、執行無序、結束無序。

啟動無序,線程是操作系統的,C# 并沒有線程,C# 需要向操作系統申請線程,假設同時或者有序向向操作系統申請線程,但操作系統并不是按順序給線程,可能后申請的先拿到線程,也可能先申請的后拿到線程。

執行無序,程序拿到了操作系統分片的線程后,我們執行的任務運氣好了可能后申請的先執行,運氣差了先申請的后執行,都是非常常見的。

結束無序,這個受執行無序、分時分片運氣、任務量的影響。開始執行無序已經說過;分時分片運氣,當我的 CPU 執行一個任務,并不是任務執行完了才會進行上下文的切換去執行其他任務,而是可以隨時暫停切換執行其他任務的;任務量就是,做的任務多少不同,即使同一時刻開始執行,完成的時間必然不一樣。

以上是“C#中異步多線程的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

中阳县| 灵宝市| 鄂尔多斯市| 沈阳市| 万安县| 株洲市| 二手房| 攀枝花市| 宜丰县| 景谷| 黄山市| 甘孜| 吕梁市| 巴彦淖尔市| 布尔津县| 舞阳县| 江北区| 盐池县| 图木舒克市| 宜昌市| 龙川县| 泌阳县| 永城市| 临海市| 运城市| 和田市| 洞口县| 淮滨县| 阳泉市| 镇坪县| 钦州市| 准格尔旗| 南投市| 望城县| 托克逊县| 巴塘县| 通河县| 简阳市| 望奎县| 洞口县| 仲巴县|