异步返回类型

在上篇文章我们简要认识了异步编程后,本章则要我们对异步的返回类型进行一定的了解和认识。 


         异步方法可以具有以下返回类型(常用):

Task返回类型 (对于执行操作但不返回任何值的异步方法)

Task<TResult> 返回类型 (对于返回值的异步方法)

Void 返回类型 (对于事件处理程序)


Task返回类型

Task返回类型是不包含 return 语句的异步方法或包含不返回操作数的 return 语句的异步方法。如果在异步方法中使用 Task 返回类型,调用方法可以使用 await 运算符暂停调用方的完成,直至被调用的异步方法结束。

 public static async Task DisplayCurrentInfoAsync()
        {
            await WaitAndApologizeAsync();

            Console.WriteLine($"今天日期是: {DateTime.Now:D}");
            Console.WriteLine($"当前时间为: {DateTime.Now.TimeOfDay:t}");
            Console.WriteLine("今天是晴天");
        }

        static async Task WaitAndApologizeAsync()
        {
            await Task.Delay(2000);

            Console.WriteLine("当前网络不好,请稍后再试\n");
        }
        // 输出:
        //    当前网络不好,请稍后再试
        //
        //    今天日期是 2022-6-8
        //    当前时间为: 12:09:24.2183304
        //    今天是晴天

Task<TResult> 返回类型

Task<TResult> 返回类型就是包含 return 语句的异步方法,其中操作数是 TResult,操作数可以简单理解成一个泛型占位符。

 public static async Task ShowTodaysInfoAsync()
        {
            string message = $"今天是: {DateTime.Today:D}\n" + "今天学习时间: " + $"{await GetLeisureHoursAsync()} 小时";
            Console.WriteLine(message);
        }

        static async Task<int> GetLeisureHoursAsync()
        {
            DayOfWeek today = await Task.FromResult(DateTime.Now.DayOfWeek);
            int leisureHours = today is DayOfWeek.Saturday || today is DayOfWeek.Sunday ? 16 : 5;
            return leisureHours;
        }
        // 输出:
        //    今天是: 2022-6-8
        //    今天学习时间:  5 小时

Void 返回类型

在异步事件处理程序中使用 void 返回类型,这需要 void 返回类型。 而这里的返回类型是指对于事件处理程序以外的不返回值,应返回 Task。此类方法的任何调用方都必须继续完成,而无需等待调用的异步方法完成。 调用方必须独立于异步方法生成的任何值或异常。

参考案例如下,均有注释说明:

 #region 生成一个点击事件Click()
        public class NaiveButton
        {
            public event EventHandler Clicked;

            public void Click()
            {
                Console.WriteLine("提出请求");
                Clicked?.Invoke(this, EventArgs.Empty);//Invoke调用,为下面MultipleEventHandlersAsync方法提供新增调用
                Console.WriteLine("通知监听器");
            }
        } 
        #endregion
        public class AsyncVoidExample
        {
            static readonly TaskCompletionSource<bool> s_tcs = new TaskCompletionSource<bool>();

            public static async Task MultipleEventHandlersAsync() //创建一个Task异步方法
            {
                Task<bool> secondHandlerFinished = s_tcs.Task;

                var button = new NaiveButton();//new 一个button对象

                //将下列的OnButtonClicked1、OnButtonClicked2Async、OnButtonClicked3的方法逐一新增到button对象里
                button.Clicked += OnButtonClicked1;
                button.Clicked += OnButtonClicked2Async;
                button.Clicked += OnButtonClicked3;

                Console.WriteLine("Click()方法被调用前");
                button.Click();//触发Click()点击事件(输出案例在底端)
                Console.WriteLine("Click()方法被调用后");

                await secondHandlerFinished;
            }

            private static void OnButtonClicked1(object sender, EventArgs e)
            {
                Console.WriteLine("   程序1启动中。。。");
                Task.Delay(100).Wait();
                Console.WriteLine("   程序1结束");
            }

            private static async void OnButtonClicked2Async(object sender, EventArgs e)
            {
                Console.WriteLine("   程序2启动中。。。");
                Task.Delay(100).Wait();
                Console.WriteLine("   程序2异步处理中");

                /*await等待Task执行延时0.5秒后输出,也对应“此类方法的任何调用方都必须继续完成,而无需等待调用的异步方法完成。”*/
                await Task.Delay(500);
                Console.WriteLine("   程序2结束");

                s_tcs.SetResult(true);
                
            }

            private static void OnButtonClicked3(object sender, EventArgs e)
            {
                Console.WriteLine("   程序3启动中。。。");
                Task.Delay(100).Wait();
                Console.WriteLine("   程序3结束");
            }
        }
        // 输出:
        //
        // 点击按钮,Click()方法被调用前
        //    提出请求
        //    程序1启动中。。。
        //    程序1结束
        //    程序2启动中。。。
        //    程序2异步处理中
        //    程序3启动中。。。
        //    程序3结束
        // 通知监听器
        // 点击按钮,Click()方法被调用后
        //    程序2结束 

最后再附带一个小技巧:当遇到微软封装好的类/方法不懂怎么使用时,选中它,按F12跳转进去就会看到里面的构造,里面都有解释说明(不出意外都是英文)。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值