欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中async await異步關(guān)鍵字用法和異步的底層原理全解析

 更新時(shí)間:2025年04月17日 11:50:12   作者:Zy100Papa  
這篇文章主要介紹了C#中async await異步關(guān)鍵字用法和異步的底層原理全解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

C#異步編程

一、異步編程基礎(chǔ)

異步編程是啥玩意兒

  • 就是讓程序在干等著某些耗時(shí)操作(比如等網(wǎng)絡(luò)響應(yīng)、讀寫文件啥的)的時(shí)候,能把線程騰出來干別的活兒,這樣程序就能更靈敏、更高效啦。
  • 跟同步編程不一樣,同步編程就是老老實(shí)實(shí)等著操作完成才繼續(xù)往下走,線程就一直被占著,多浪費(fèi)啊。

異步編程的好處

  • 響應(yīng)快:比如在做UI界面的時(shí)候,用了異步編程,界面就不會(huì)卡啦,用戶體驗(yàn)賊棒。
  • 省資源:不用讓線程一直干等著,資源利用率就上去了。
  • 能扛更多活兒:面對(duì)一大堆并發(fā)操作的時(shí)候,異步編程能輕松搞定,擴(kuò)展性杠杠滴。

二、異步方法的工作原理

異步方法咋被編譯的

  • 你寫個(gè)async修飾的方法,編譯器就把它變成一個(gè)狀態(tài)機(jī)啦。
  • 狀態(tài)機(jī)會(huì)根據(jù)await表達(dá)式把方法拆成好多個(gè)狀態(tài),就跟玩拼圖一樣。

狀態(tài)機(jī)是咋干活的

  • 狀態(tài)機(jī)就是編譯器生成的一個(gè)類,它得記著異步方法執(zhí)行到哪兒了。
  • 核心就是MoveNext方法,它就像導(dǎo)演一樣,指揮著異步操作一步步往下走。
  • 每碰到一個(gè)await,就切換一下狀態(tài)。

await底層是咋實(shí)現(xiàn)的

  • await就整出個(gè)等待器(awaiter),專門等著異步操作完成。
  • 要是操作還沒完,await就記下當(dāng)前狀態(tài),等操作完了再繼續(xù)往下走。

三、代碼示例

HttpClient干異步網(wǎng)絡(luò)請(qǐng)求

  • 弄個(gè)HttpClient對(duì)象,用來發(fā)HTTP請(qǐng)求。
  • GetStringAsync方法,就能異步拿到指定URL的網(wǎng)頁(yè)內(nèi)容啦。
  • 把拿到的內(nèi)容打印出來,瞧一瞧成果。
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace asyncawait原理1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                string html = await httpClient.GetStringAsync("https://www.baidu.com");
                Console.WriteLine(html);
            }
        }
    }
}

異步讀寫文件

  • File.WriteAllTextAsync方法,能把文本異步寫到指定路徑的文件里。
  • File.ReadAllTextAsync方法,就能把文件內(nèi)容異步讀出來。
  • 把讀到的內(nèi)容打印出來,看看對(duì)不對(duì)。
using System;
using System.IO;
using System.Threading.Tasks;
namespace asyncawait原理1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string txt = "hello world";
            string filename = @"E:\temp\1.txt";
            await File.WriteAllTextAsync(filename, txt);
            Console.WriteLine("寫入成功");
            string s = await File.ReadAllTextAsync(filename);
            Console.WriteLine("文件內(nèi)容:" + s);
        }
    }
}

四、編譯后的底層實(shí)現(xiàn)

用ILSpy反編譯DLL文件

  • ILSpy就是個(gè)反編譯工具,能把DLL文件變回C#代碼,方便咱們研究。
  • 把DLL文件加載到ILSpy里,就能看到編譯后的代碼啦。
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0 : IAsyncStateMachine
{
    public int <>1__state;
    public AsyncTaskMethodBuilder <>t__builder;
    public string[] args;
    private string <>s__1;
    private string <>s__3;
    private string <>s__6;
    private HttpClient <httpClient>__4;
    private string <html>__5;
    private string <txt>__2;
    private string <filename>__7;
    private void MoveNext()
    {
        int num = this.<>1__state;
        try
        {
            TaskAwaiter<string> awaiter;
            TaskAwaiter awaiter2;
            switch (num)
            {
                default:
                    this.<httpClient>__4 = new HttpClient();
                    goto case 0;
                case 0:
                    try
                    {
                        awaiter = this.<httpClient>__4.GetStringAsync("https://www.baidu.com").GetAwaiter();
                        if (!awaiter.IsCompleted)
                        {
                            num = this.<>1__state = 0;
                            this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
                            return;
                        }
                    }
                    catch (Exception exception)
                    {
                        this.<>1__state = -2;
                        this.<>t__builder.SetException(exception);
                        return;
                    }
                    this.<html>__5 = awaiter.GetResult();
                    Console.WriteLine(this.<html>__5);
                    this.<txt>__2 = "hello yz";
                    this.<filename>__7 = @"E:\temp\1.txt";
                    awaiter2 = File.WriteAllTextAsync(this.<filename>__7, this.<txt>__2).GetAwaiter();
                    if (!awaiter2.IsCompleted)
                    {
                        num = this.<>1__state = 1;
                        this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);
                        return;
                    }
                    break;
                case 1:
                    awaiter2 = this.<>s__1;
                    this.<>s__1 = null;
                    num = this.<>1__state = -1;
                    break;
            }
            awaiter2.GetResult();
            Console.WriteLine("寫入成功");
            this.<>s__3 = null;
            awaiter = File.ReadAllTextAsync(this.<filename>__7).GetAwaiter();
            if (!awaiter.IsCompleted)
            {
                num = this.<>1__state = 2;
                this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
                return;
            }
            this.<>s__6 = awaiter.GetResult();
            Console.WriteLine("文件內(nèi)容:" + this.<>s__6);
            this.<>s__6 = null;
            this.<>t__builder.SetResult();
        }
        catch (Exception exception)
        {
            this.<>1__state = -2;
            this.<>t__builder.SetException(exception);
            return;
        }
        this.<>1__state = -1;
    }
    void IAsyncStateMachine.MoveNext()
    {
        // This method is implemented by the compiler-generated code.
    }
    [DebuggerHidden]
    private void SetStateMachine(IAsyncStateMachine stateMachine)
    {
        this.<>t__builder.SetStateMachine(stateMachine);
    }
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        this.SetStateMachine(stateMachine);
    }
}

看看編譯后的狀態(tài)機(jī)代碼

  • 分析狀態(tài)機(jī)類的結(jié)構(gòu),看看都有啥變量、MoveNext方法長(zhǎng)啥樣。
  • 瞧瞧awaiter咋用的,狀態(tài)咋切換的。

理解MoveNext方法是干啥的

  • MoveNext就是狀態(tài)機(jī)的發(fā)動(dòng)機(jī),它決定了異步方法咋執(zhí)行。
  • 在這個(gè)方法里,會(huì)根據(jù)當(dāng)前狀態(tài)執(zhí)行對(duì)應(yīng)的代碼,碰到await就暫停,安排好后續(xù)咋繼續(xù)。

五、總結(jié)

異步方法編譯過程回顧

  • 再嘮嘮async方法咋被編譯成狀態(tài)機(jī)的,狀態(tài)機(jī)又咋根據(jù)await拆分方法、驅(qū)動(dòng)異步操作的。

await到底在干啥

  • 說白了,await根本不是真的“等待”,而是靠狀態(tài)機(jī)和等待器來實(shí)現(xiàn)的異步協(xié)作。
  • 強(qiáng)調(diào)一下異步編程的好處,比如響應(yīng)快、省資源、能扛更多活兒,還有啥場(chǎng)景適合用它。

到此這篇關(guān)于C#中async await異步關(guān)鍵字用法和異步的底層原理的文章就介紹到這了,更多相關(guān)C# async await異步關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#結(jié)合JavaScript實(shí)現(xiàn)上傳視頻到騰訊云點(diǎn)播平臺(tái)的操作方法

    C#結(jié)合JavaScript實(shí)現(xiàn)上傳視頻到騰訊云點(diǎn)播平臺(tái)的操作方法

    這篇文章主要介紹了C#結(jié)合JavaScript實(shí)現(xiàn)上傳視頻到騰訊云點(diǎn)播平臺(tái),上傳視頻功能,主要要解決兩個(gè)問題,一是在服務(wù)端通過C#生成簽名和SDKID,二是在客戶端通過JavaScript上傳視頻到騰訊云點(diǎn)播服務(wù)器,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • Unity中協(xié)程IEnumerator的使用方法介紹詳解

    Unity中協(xié)程IEnumerator的使用方法介紹詳解

    本文主要介紹了Unity中協(xié)程IEnumerator的使用方法介紹詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 一文探索C#中實(shí)現(xiàn)雙向鏈表的方法

    一文探索C#中實(shí)現(xiàn)雙向鏈表的方法

    這篇文章主要為大家詳細(xì)介紹了C#中的雙向鏈表的實(shí)現(xiàn),揭秘雙向鏈表內(nèi)實(shí)現(xiàn)諸多方法的那些事,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • 使用C#和OpenXML讀取大型Excel文件

    使用C#和OpenXML讀取大型Excel文件

    OpenXML 是辦公文檔(Word、Excel、PowerPoint)的開放標(biāo)準(zhǔn),允許以編程方式操作這些文檔,本文主要介紹了C#如何利用OpenXML讀取大型Excel文件,感興趣的可以了解下
    2024-11-11
  • C#實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能(2)(窗體應(yīng)用)

    C#實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能(2)(窗體應(yīng)用)

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Unity游戲開發(fā)實(shí)現(xiàn)背包系統(tǒng)的示例詳解

    Unity游戲開發(fā)實(shí)現(xiàn)背包系統(tǒng)的示例詳解

    這篇文章主要為大家介紹了Unity游戲開發(fā)實(shí)現(xiàn)背包系統(tǒng)的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • C# 引入委托的目的是什么

    C# 引入委托的目的是什么

    這篇文章主要介紹了C# 引入委托的目的是什么,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>

    C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>

    這篇文章主要介紹了C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-02-02
  • Winform控件優(yōu)化之圓角按鈕2

    Winform控件優(yōu)化之圓角按鈕2

    這篇文章主要介紹了Winform控件優(yōu)化之圓角按鈕2,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-08-08
  • unity實(shí)現(xiàn)UI元素跟隨3D物體

    unity實(shí)現(xiàn)UI元素跟隨3D物體

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)UI元素跟隨3D物體,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評(píng)論