async 和 await 的进阶

异常的捕获:

static void Main(string[] args)
        {
            //继续我们的异步编程的使用嘀呀;
            //关于主线程是无法捕获我们子线程中的异常滴滴啊;

            var t = DoExceptionAsync();
            t.Wait();
            Console.WriteLine($"{nameof(t.Status)}: {t.Status}");   //任务状态
            Console.WriteLine($"{nameof(t.IsCompleted)}: {t.IsCompleted}");     //任务完成状态标识
            Console.WriteLine($"{nameof(t.IsFaulted)}: {t.IsFaulted}");     //任务是否有未处理的异常标识

            Console.ReadLine();
        }
        private static async Task DoExceptionAsync()
        {
            try
            {

                await Task.Run(() => { throw new Exception(); });
            }
            catch (Exception e)
            {
                Console.WriteLine($"{nameof(DoExceptionAsync)} 出现异常!,异常时:{e.Message.ToString()}");
            }
        }
    }

结果:

 

也许你有疑问:

但是:因为:任务没有被取消,并且异常都已经处理完成!

在调用方法中同步等待任务

算了,这个太简单了,有任务的等待,也有任务的取消,.......

代码;

 private static void Main(string[] args)
        {
            var t = CountCharactersAsync("http://www.cnblogs.com/liqingwen/");

            t.Wait();   //等待任务结束
            Console.WriteLine($"Result is {t.Result}");

            Console.Read();
        }

        /// <summary>
        /// 统计字符数量
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private static async Task<int> CountCharactersAsync(string address)
        {
            var result = await Task.Run(() => new WebClient().DownloadStringTaskAsync(address));
            return result.Length;
        }

这里还有我们两个静态的方法:可采用 Task 的两个静态方法 WaitAll() 和 WaitAny() 。

  private static int time = 0;
        static void Main(string[] args)
        {


            var t1 = CountCharactersAsync("http://www.cnblogs.com/liqingwen/",1);
            var t2 = GetRandomAsyn(2);

            //Task 还以见数组地哦;
            Task<int>[] tasks = new Task<int>[] {t1,t2};
            Task.WaitAll(tasks);

            //或则:Task.WaitAny(tasks); 


            Console.WriteLine($"t1.{nameof(t1.IsCompleted)}: {t1.IsCompleted}");
            Console.WriteLine($"t2.{nameof(t2.IsCompleted)}: {t2.IsCompleted}");

            Console.ReadLine();
        }


        /// <summary>
        /// 统计字符数量
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private static async Task<int> CountCharactersAsync(string address,int id)
        {
            var result = await Task.Run(() => new WebClient().DownloadStringTaskAsync(address));
            Console.WriteLine($"{id} 已经调用完成");
            return result.Length;
        }
        //获取一个随机数

        private static async Task<int> GetRandomAsyn(int id)
        {
            var num = await Task.Run(() =>
             {
                 time++;
                 Thread.Sleep(time * 100);
                 return new Random().Next();
             });
            Console.WriteLine($"{id} 已经调用完成");
            return num;
        }

    }

在异步方法中异步等待任务

继续我们的异步编程之路........

class Program
    {
        private static int time = 0;
        static void Main(string[] args)
        {
            //继续我们的异步编程地呀;
            var t = GetRandomAsync();
            Console.WriteLine("mian line 1");  //【注意】WhenAll() 异步等待集合内的 Task 都完成,不会占用主线程的时间。
            Console.WriteLine($"Result: {t.Result}"); //但是这里会堵塞id呀;
            Console.WriteLine("mian line 2");
            Console.Read();


        }

        private static async Task<int> GetRandomAsync()
        {
            time++;
            var t1 = Task.Run(()=>
            {
                Thread.Sleep(time* 600);
                return new Random().Next();
            });

            time++;
           var t2 = Task.Run(() =>
             {
                  Thread.Sleep(time*600);
                  return new Random().Next();
             });

            //这里开启了两个异步的任务;
            await Task.WhenAll(new List<Task<int>>() { t1, t2 }); //【注意】WhenAll() 异步等待集合内的 Task 都完成,不会占用主线程的时间。

            // await Task.WhenAny(new List<Task<int>>() { t1, t2 });

            Console.WriteLine($"  t1.{nameof(t1.IsCompleted)}: {t1.IsCompleted} ");
            Console.WriteLine($"  t2.{nameof(t2.IsCompleted)}:{t2.IsCompleted } ");

            return t1.Result + t2.Result; //这个就返回了 我们想要的基本值滴呀;

        }
    }

结果:

如果该成whenAny的结果:

 

 ps:以上结果是有不确定性呀,你懂滴哦;

Task.Delay() 暂停执行

 这个其实是Thread.sleep的一种取代方法地呀;

 private static void Main(string[] args)
        {
            Console.WriteLine($"{nameof(Main)} - start.");
            DoAsync();
            Console.WriteLine($"{nameof(Main)} - end.");

            Console.Read();
        }

        private static async void DoAsync()
        {
            Console.WriteLine($"    {nameof(DoAsync)} - start.");

           await Task.Delay(500);

            Console.WriteLine($"    {nameof(DoAsync)} - end.");
        }

结果哦:

原文地址:https://www.cnblogs.com/mc67/p/6256705.html