C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# async await异步关键字

C#中async await异步关键字用法和异步的底层原理全解析

作者:Zy100Papa

这篇文章主要介绍了C#中async await异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

C#异步编程

一、异步编程基础

异步编程是啥玩意儿

异步编程的好处

二、异步方法的工作原理

异步方法咋被编译的

状态机是咋干活的

await底层是咋实现的

三、代码示例

HttpClient干异步网络请求

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);
            }
        }
    }
}

异步读写文件

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("文件内容:" + s);
        }
    }
}

四、编译后的底层实现

用ILSpy反编译DLL文件

[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("文件内容:" + 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);
    }
}

看看编译后的状态机代码

理解MoveNext方法是干啥的

五、总结

异步方法编译过程回顾

await到底在干啥

到此这篇关于C#中async await异步关键字用法和异步的底层原理的文章就介绍到这了,更多相关C# async await异步关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文