.NET Core异步编程

目录

一、什么是异步编程

为什么要使用异步编程?

二、async和await的基本使用

三、异步方法不等于多线程

四、CancellationToken参数

五.异步与yield


一、什么是异步编程

        近些年,.NET增加了很多新特新,异步编程就是期中之一。因为.Net的异步编程模型把复杂的异步编程变得简单易用。使得开发人员可以轻松开发出更高效的应用程序

为什么要使用异步编程?

        就拿点餐来说,我们去餐馆里面吃饭,一般都是我们进去找位置坐下,然后服务员拿着菜单过来,让我们进行点餐,同时服务员在旁边等待,等我们点完了,再拿给后厨进行炒菜,随后服务下一位客人,这一种方式称为同步点餐。第二种就是我们进去坐下,服务员过来会给我们一个餐单,让我们自己点,同时下一个客人进来,她会重复同样的操作,把菜单给顾客,等到我们点完了,再招呼她过来拿走菜单,这称为异步点餐,也就是要说的异步编程。前者服务员会一直在你身边,这样会浪费服务员等待的时间,并且当店里忙的时候,别的顾客会不爽。而后者则充分利用了服务员等待的这段时间,让这段时间去干另外的事情,服务更多的顾客,尽管服务一个人的总时间有可能会增加,但覆盖范围非常全面。

二、async和await的基本使用

异步方法:用async关键字修饰的一种方法。

(1)异步方法的返回值一般是Task<T>,T是真正的返回值类型,如Task<int>,惯例:异步方法名字一般以Async结尾

(2)即使方法没有返回值,也最好把返回值声明为非泛型的Task

(3)调用异步方法时,一般在方法面前加await,这样返回值类型就是泛型指定的T类型

(4)异步方法的“传染性”:一个方法中如果有await调用,则这个方法必须用async修饰

异步方法的使用:

static async Task Main(string[] args)
        {
            await DownloadAsync("https://www.taobao.com",@"d:\study core\1.txt");
            Console.WriteLine("ok");
        }
        static async Task DownloadAsync(string url, string filename) 
        {
            using (HttpClient httpClient = new HttpClient()) {
                string html =  await httpClient.GetStringAsync(url);
                await File.WriteAllTextAsync(filename, html);
            }
        }

注:如果同样的功能,既有同步方法,也有异步方法,优先使用异步方法

三、异步方法不等于多线程

 static async Task Main(string[] args)
        {
            Console.WriteLine("之前ID: " + Thread.CurrentThread.ManagedThreadId);
            await CalcAsync(5000);
            Console.WriteLine("之后: " + Thread.CurrentThread.ManagedThreadId);
        }

        //n个随机数相加
        static async Task<double> CalcAsync(int n)
        {
            Console.WriteLine("CalcAsync: " + Thread.CurrentThread.ManagedThreadId);
            double result = 0;
            Random random = new Random();
            for (var i = 0; i < n*n; i++) { 
                result += random.NextDouble();
            }
            return result;
        }

 注:异步方法并不会自主的在新的线程当中去执行,只有调用Task.Run(),放到新的线程当中去执行。有的异步方法是没有标注async的,并且异步方法不要使用sleep(会阻塞总线程),如果要延时操作,请使用await Task.Delay();

四、CancellationToken参数

        用于获得提前终止执行的信号

 static async Task Main(string[] args)
        {
   
            CancellationTokenSource sts = new CancellationTokenSource();
            sts.CancelAfter(1000);
            CancellationToken cotken = sts.Token;
            await DownloadAsync("https://www.taobao.com", 100, cotken);
        }

        static async Task DownloadAsync(string url, int n, CancellationToken cancellationToken)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                for (int i = 0; i < n; i++)
                {
                    string html = await httpClient.GetStringAsync(url);
                    Console.WriteLine($"{DateTime.Now}:{html}");
                    if (cancellationToken.IsCancellationRequested)
                    {
                        Console.WriteLine("请求被取消");
                        break;
                    }
                }
            }
        }

将正在打印的网址内容在一秒后取消这个请求。

五.异步与yield

        yield不仅能够简化数据的返回,而且可以让数据“流水线化”,从而提升整体的性能

在旧版本c#中,async方法中不能使用yield。但在之后的版本中,可以使用IAsyncEnumerable修饰这个方法,从而使得这个方法可以使用yield,但调用该方法的时候必须使用await,如图:

static async Task Main(string[] args)
        {
           await foreach (var i in Test2()) {
                Console.WriteLine(i);
            }
        }

        static async IAsyncEnumerable<string> Test2()
        {
            yield return("wdqdw");
            yield return ("okok");
            yield return ("51268");
        }        
运行结果:wdqdw
          okok
          51268

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捕不到月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值