最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

C#異步編程

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

異步編程是啥玩意兒

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

異步編程的好處

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

二、異步方法的工作原理

異步方法咋被編譯的

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

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

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

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

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

三、代碼示例

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

  • 弄個HttpClient對象,用來發(fā)HTTP請求。
  • GetStringAsync方法,就能異步拿到指定URL的網(wǎng)頁內(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)容打印出來,看看對不對。
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就是個反編譯工具,能把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方法長啥樣。
  • 瞧瞧awaiter咋用的,狀態(tài)咋切換的。

理解MoveNext方法是干啥的

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

五、總結(jié)

異步方法編譯過程回顧

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

await到底在干啥

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

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

相關(guān)文章

最新評論

利津县| 昭通市| 阿拉善右旗| 西充县| 台东市| 宿州市| 旬阳县| 益阳市| 九寨沟县| 阜城县| 合肥市| 靖宇县| 抚州市| 安福县| 仪征市| 金华市| 姜堰市| 湟中县| 册亨县| 民权县| 孙吴县| 政和县| 五台县| 岗巴县| 兴宁市| 宁海县| 澳门| 茌平县| 延津县| 化德县| 永德县| 武平县| 祁阳县| 宁城县| 稻城县| 密山市| 基隆市| 广丰县| 临洮县| 亳州市| 梁平县|