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

写了段小代码,给同事演示一下这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  Begin
2. 线程:1  Into  DisplayValue
3. 线程:1  Into  GetValueAsync
4. 线程:1  Middle  DisplayValue
5. 线程:3  Into  GetValueAsync Task
6. 线程:1  End
7. 线程:3  out  GetValueAsync Task
8. 线程:3  out  GetValueAsync
9. 线程:3  Value is : 2.47032822920623E-322
10. 线程: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  Begin
2. 线程:1  Into  DisplayValue
3. 线程:1  Into  GetValueAsync
4. 线程:1  out  GetValueAsync
5. 线程:3  Into  GetValueAsync Task
6. 线程:1  Middle  DisplayValue
7. 线程:1  End
8. 线程:3  out  GetValueAsync Task
9. 线程:3  Value is : 2.47032822920623E-322
10. 线程:3  Out  DisplayValue

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

你可能感兴趣的:(.Net技术)