演示C#里的async和await的使用

来源:互联网 发布:抗氧化护肤品知乎 编辑:程序博客网 时间:2024/06/09 16:32

写了段小代码,给同事演示一下这2个语法糖的代码执行顺序:

class Program    {        static void Main()        {            Msg("Begin");            DisplayValue();            Msg("End");            Console.Read();        }        #region async 测试        public static async Task<double> GetValueAsync(double num1, double num2)        {            Msg("Into  GetValueAsync");            var ret = await Task.Run(() =>            {                Msg("Into  GetValueAsync Task");                for (int i = 0; i < 1000000; i++)                    num1 = num1 / num2;                Msg("out  GetValueAsync Task");                return num1;            });            Msg("out  GetValueAsync");            return ret;        }        public static async void DisplayValue()        {            Msg("Into  DisplayValue");            var result = GetValueAsync(1234.5, 1.01);            Msg("Middle  DisplayValue");            Msg("Value is : " + await result);            Msg("Out  DisplayValue");        }        #endregion        private static int idx;        static void Msg(string msg)        {            Interlocked.Increment(ref idx);            var id = Thread.CurrentThread.ManagedThreadId.ToString();            Console.WriteLine(idx.ToString() + ". 线程:" + id + "  " + msg);            Thread.Sleep(100); // 避免cpu不定,导致顺序打乱        }    }

代码执行结果:

1. 线程:1  Begin2. 线程:1  Into  DisplayValue3. 线程:1  Into  GetValueAsync4. 线程:1  Middle  DisplayValue5. 线程:3  Into  GetValueAsync Task6. 线程:1  End7. 线程:3  out  GetValueAsync Task8. 线程:3  out  GetValueAsync9. 线程:3  Value is : 2.47032822920623E-32210. 线程:3  Out  DisplayValue

把GetValueAsync方法的async和await 移除

public static Task<double> GetValueAsync(double num1, double num2){    Msg("Into  GetValueAsync");    var ret = Task.Run(() =>    {        Msg("Into  GetValueAsync Task");        for (int i = 0; i < 1000000; i++)            num1 = num1 / num2;        Msg("out  GetValueAsync Task");        return num1;    });    Msg("out  GetValueAsync");    return ret;}

执行顺序就变了,结果如下:

1. 线程:1  Begin2. 线程:1  Into  DisplayValue3. 线程:1  Into  GetValueAsync4. 线程:1  out  GetValueAsync5. 线程:3  Into  GetValueAsync Task6. 线程:1  Middle  DisplayValue7. 线程:1  End8. 线程:3  out  GetValueAsync Task9. 线程:3  Value is : 2.47032822920623E-32210. 线程:3  Out  DisplayValue

你看明白了吗?如果不明白,把上面的测试代码复制到你的项目里,改一改,运行一下吧,
简单总结一下:
- await指令调起线程执行异步方法和方法内后面的代码
- await指令会阻塞当前方法后面的代码,但是不会阻塞外部调用
- await必须搭配async使用,而async不一定需要有await

原创粉丝点击