risc-v中文社区

 找回密码
 立即注册
查看: 8999|回复: 3

[原创] async/await异步执行

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-8 17:12:36 | 显示全部楼层 |阅读模式
public static string DateTime_Now_ToString()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
        }
        public static string procstr(string arg)
        {
            Thread.Sleep(4000);
            return arg + "test";
        }
        private static async Task<string> GetAwaitString(string str)
        {
            /*
                async Task<string> GetAwaitRunString(string str) 方法内部是同步执行的。
                直到运行到 await 关键字(内部)是异步执行的(使用后台线程池)。
             */
            Console.WriteLine("GetAwaitString await前:\t线程Id:【{0}】\t后台线程:【{1}】\t使用线程池:【{2}】\t当前时间:【{3}】",
                Environment.CurrentManagedThreadId.ToString(),
                Thread.CurrentThread.IsBackground,
                Thread.CurrentThread.IsThreadPoolThread,
                DateTime_Now_ToString());

            var task = await System.Threading.Tasks.Task.Run<string>(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("GetAwaitString await后:\t线程Id:【{0}】\t后台线程:【{1}】\t使用线程池:【{2}】\t当前时间:【{3}】",
                Environment.CurrentManagedThreadId.ToString(),
                Thread.CurrentThread.IsBackground,
                Thread.CurrentThread.IsThreadPoolThread,
                DateTime_Now_ToString());
                return str + "," + DateTime_Now_ToString();
            });

            Console.WriteLine("before return" + Environment.CurrentManagedThreadId);//这一句看起来不能执行,其实,只能是btn的click事件处理完之后才会再次进到此以主线程身份执行
            var task2 = await System.Threading.Tasks.Task.Run<string>(() =>
            {
                return procstr(task);
            });
            Console.WriteLine("task2=" + task2);
            return task;
        }
private void btnNAstart_Click(object sender, EventArgs e)
        {
            Console.WriteLine("主线程:\t\t\t线程Id:【{0}】\t后台线程:【{1}】\t使用线程池:【{2}】\t当前时间:【{3}】",
                Environment.CurrentManagedThreadId,
                Thread.CurrentThread.IsBackground,
                Thread.CurrentThread.IsThreadPoolThread,
                DateTime_Now_ToString());
            var rlt =  GetAwaitString("abcd123");
            Console.WriteLine("结果:" + rlt); //无意义的值
            //Console.WriteLine("结果:" + rlt.Result); //rlt.Result则就一定会阻塞
           //也就是说,如果本btn click事件代码是另一个线程或task中代码,那么可以用rlt.Result待方式取得异步执行的值
            Console.WriteLine("执行完毕:" + DateTime_Now_ToString());
       }


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-6-9 09:28:39 | 显示全部楼层
有一个要点:Task.Result会直接阻塞当前调用线程,而aysnc、await机制是使用状态机切换上下文
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-6-9 13:53:08 | 显示全部楼层
关于Task的异常:
与Thread不一样,Task可以很方便的传播异常 如果你的task里面抛出了一个未处理的异常,那么该异常就会重新被抛出给:

调用了wait()的地方
访问了Task的Reuslt属性的地方。
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-6-9 13:56:07 | 显示全部楼层
还有一个网页可参考:c#异步编程-Task(一) https://zhuanlan.zhihu.com/p/310646064
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-24 23:50 , Processed in 0.014923 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表