阅读目录:

  1. 基本介绍
  2. 基本原理剖析
  3. 内部实现剖析
  4. 重点注意的地方
  5. 总结

基本介绍

Async、Await是net4.x新增的异步编程方式,其目的是为了简化异步程序编写,和之前APM方式简单对比如下。

APM方式,BeginGetRequestStream需要传入回调函数,线程碰到BeginXXX时会以非阻塞形式继续执行下面逻辑,完成后回调先前传入的函数。

    HttpWebRequest myReq =(HttpWebRequest)WebRequest.Create("http://cnblogs.com/");
     myReq.BeginGetRequestStream();
     //to do

Async方式,使用Async标记Async1为异步方法,用Await标记GetRequestStreamAsync表示方法内需要耗时的操作。主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑。当await耗时操作完成时,继续执行Async1下面的逻辑

static async void Async1()
    {
        HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://cnblogs.com/");
        await myReq.GetRequestStreamAsync();
        //to do
    }     

上面是net类库实现的异步,如果要实现自己方法异步。
APM方式:

        public delegate int MyDelegate(int x);   
        MyDelegate mathDel = new MyDelegate((a) => { return 1; });
         mathDel.BeginInvoke(1, (a) => { },null);

Async方式:

static async void Async2()
    {
        await Task.Run(() => { Thread.Sleep(500); Console.WriteLine("bbb"); });
        Console.WriteLine("ccc");
    }
  Async2();
  Console.WriteLine("aaa");

对比下来发现,async/await是非常简洁优美的,需要写的代码量更少,更符合人们编写习惯。
因为人的思维对线性步骤比较好理解的。

APM异步回调的执行步骤是:A逻辑->假C回调逻辑->B逻辑->真C回调逻辑,这会在一定程度造成思维的混乱,当一个项目中出现大量的异步回调时,就会变的难以维护。
Async、Await的加入让原先这种混乱的步骤,重新拨正了,执行步骤是:A逻辑->B逻辑->C逻辑。

基本原理剖析

作为一个程序员的自我修养,刨根问底的好奇心是非常重要的。 Async刚出来时会让人有一头雾水的感觉,await怎么就直接返回了,微软怎么又出一套新的异步模型。那是因为习惯了之前的APM非线性方式导致的,现在重归线性步骤反而不好理解。 学习Async时候,可以利用已有的APM方式去理解,以下代码纯属虚构
比如把Async2方法想象APM方式的Async3方法:

static async void Async3()
    {
        var task= await Task.Run(() => { Thread.Sleep(500); Console.WriteLine("bbb"); });
       //注册task完成后回调
        task.RegisterCompletedCallBack(() =>
        {
            Console.WriteLine("ccc");
        });
    }

上面看其来就比较好理解些的,再把Async3方法想象Async4方法:

static  void Async4()
    {
        var thread = new Thread(() =>
         {
             Thread.Sleep(500);
             Console.WriteLine("bbb");
         });
        //注册thread完成后回调
        thread.RegisterCompletedCallBack(() =>
        {
            Console.WriteLine("ccc");
        });
        thread.Start();
    }

这样看起来就非常简单明了,连async都去掉了,变成之前熟悉的编程习惯。虽然代码纯属虚构,但基本思想是相通的,差别在于实现细节上面。

内部实现剖析

作为一个程序员的自我修养,严谨更是不可少的态度。上面的基本思想虽然好理解了,但具体细节呢,编程是个来不得半点虚假的工作,那虚构的代码完全对不住看官们啊。

继续看Async2方法,反编译后的完整代码如下:

internal class Program
{
    // Methods
    [AsyncStateMachine(typeof(<Async2>d__2)), DebuggerStepThrough]
    private static void Async2()
    {
        <Async2>d__2 d__;
        d__.<>t__builder = AsyncVoidMethodBuilder.Create();
        d__.<>1__state = -1;
        d__.<>t__builder.Start<<Async2>d__2>(ref d__);
    }

    private static void Main(string[] args)
    {
        Async2();
        Console.WriteLine("aaa");
        Console.ReadLine();
    }

    // Nested Types
    [CompilerGenerated]
    private struct <Async2>d__2 : IAsyncStateMachine
    {
        // Fields
        public int <>1__state;
        public AsyncVoidMethodBuilder <>t__builder;
        private object <>t__stack;
        private TaskAwaiter <>u__$awaiter3;

        // Methods
        private void MoveNext()
        {
            try
            {
                TaskAwaiter awaiter;
                bool flag = true;
                switch (this.<>1__state)
                {
                    case -3:
                        goto Label_00C5;

                    case 0:
                        break;

                    default:
                        if (Program.CS$<>9__CachedAnonymousMethodDelegate1 == null)
                        {
                            Program.CS$<>9__CachedAnonymousMethodDelegate1 = new Action(Program.<Async2>b__0);
                        }
                        awaiter = Task.Run(Program.CS$<>9__CachedAnonymousMethodDelegate1).GetAwaiter();
                        if (awaiter.IsCompleted)
                        {
                            goto Label_0090;
                        }
                        this.<>1__state = 0;
                        this.<>u__$awaiter3 = awaiter;
                        this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, Program.<Async2>d__2>(ref awaiter, ref this);
                        flag = false;
                        return;
                }
                awaiter = this.<>u__$awaiter3;
                this.<>u__$awaiter3 = new TaskAwaiter();
                this.<>1__state = -1;
            Label_0090:
                awaiter.GetResult();
                awaiter = new TaskAwaiter();
                Console.WriteLine("ccc");
            }
            catch (Exception exception)
            {
                this.<>1__state = -2;
                this.<>t__builder.SetException(exception);
                return;
            }
        Label_00C5:
            this.<>1__state = -2;
            this.<>t__builder.SetResult();
        }

        [DebuggerHidden]
        private void SetStateMachine(IAsyncStateMachine param0)
        {
            this.<>t__builder.SetStateMachine(param0);
        }
    }

    public delegate int MyDelegate(int x);
}

 
Collapse Methods
 
View Code

相关文章:

  • 2022-01-10
  • 2022-12-23
  • 2022-02-13
  • 2021-09-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-18
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-06-29
  • 2022-12-23
  • 2021-07-21
  • 2021-12-27
相关资源
相似解决方案