杨中科Asp.NET Core教程笔记

开始

  • C#入门书籍

    • C#图解教程
    • C#入门经典
  • 视频地址

  • 最开始 .Net 代表了 net core , .net Framework,但现在默认 .NET 就是指的.NET Core

  • .Net Standard :是规范,.net core , .net Framework等.net技术需要实现.Net Standard中定义的类、方法杨中科Asp.NET Core教程笔记_第1张图片

    • 可以理解为.Net Standard规定了公共的类,而其他的例如.net core , .net Freamwork在其基础上又添加了自己特有的类
    • .Net Standard只是标准,不提供实现

1. NuGet

  • NuGet官网
    • 当不知道包名的时候,可以在官网通过需求关键字搜索相应的包
    • 官网里面有些包没有写依赖 Dependencies,一般就是依赖于.net Framework (一般是很老的包没有依赖)
    • 版本号中alpha、Beta都是非正式版的标识(不稳定)

1.1 通过命令行方式使用NuGet

  • Package Manager方式

    • 在VS的程序包管理器控制台添加包

      • 在这里插入图片描述

      • 杨中科Asp.NET Core教程笔记_第2张图片

      • 默认项目选择将包装到指定项目

      • 命令不带 -Version 则默认安装最新稳定版

    • 更新包Update-package+包名

    • 删除包UnInstall-Package+包名(其实就是在原命令上加Un

    • 双击项目名可看到安装的包

      <ItemGroup>
          <PackageReference Include="Zack.EFCore.Batch" Version="1.6.3" />
      ItemGroup>
      
    • 如果界面没有程序包管理器,在视图中去找

  • .Net CLI方式

    • 直接在CMD命令行进行包的添加(需要进入项目路径中)
    • 在这里插入图片描述

1.2 通过图形界面使用

  • NuGet包管理器
  • 在批量删除、更新包的时候图形界面更方便

1.3 内部部署Nuget包

  • 公司内部可以搭建自己的Nuget服务器,仅限内部使用

2. 异步编程:async、await

2.1 开始

  • 简单理解异步:“不等”
  • 异步编程并不能加快单个请求的处理速度,但是可以让web服务器处理更多的请求(提高系统并发量)
  • 异步不是多线程
  • async、await不等于多线程,但是可以简化多线程程序的开发

2.2 async、await基本使用

  • 异步方法定义:用async关键字修饰的方法
    1. 异步方法的返回值一般是Task,T是真正的返回值类型,例如Task

      • 异步方法的命名常以Async结尾
    2. 即使方法没有返回值,也最好将返回值写为Task,不要写成Void

      • 写成void容易出现问题
    3. 调用泛型方法时,一般会在该方法前面加上await关键字

      • 这样拿到的返回值就是泛型指定的T类型

        int i=await FuncAsync();
        //await使得Task中的i被解析出来了
        
    4. 如果一个方法中有await,则这个方法也必须被async关键字修饰

      • 如果方法被async关键字修饰,在内部调用异步方法不写await也可以执行,编译器只是会警告

2.3 编写异步方法

  • 对于同步、异步都实现的方法,推荐调用异步方法

  • 对于在一个同步方法中,不得不调用异步方法时,可以使用Result或者Wait()

    • 对于一个有返回值Task的异步方法,想要不使用await拿到T类型的值(也就是同步调用的方式调用这个异步方法),可以通过Task的Result属性实现

      • 使用方式就是在异步方法后面 .Result

        • int i=FuncAsync().Result;
          //上面的语句等同于
          Task t=FuncAsync();
          int i=t.Result;
          
    • 对于一个没有返回值异步方法,想要不使用await调用这个异步方法(也就是同步调用的方式调用这个异步方法),可以通过Task的wait方法实现

      • 例如在一个只能是同步的方法FunA()中调用这个异步方法,就需要将这个异步方法调用wait方法

        • int FuncA()
          {
          	FuncAsync().Wait();
          }
          
    • 注意:如果调Wait或者Result,容易出现死锁的情况(表现就是程序卡住了)

  • 在lamda表达式中调用异步方法(例如委托),直接调用会报错,可以在lamda表达式前加上async关键字,将lamda表达式修饰为异步的,如:

    fun(await ()=>{
    	await FuncAsync();
    });
    

2.4 async、await原理

  • async、await是“语法糖”,最终会编译成状态机调用
  • async的方法会被C#编译器编译成一个类,会主要根据await调用进行切分为多个状态,对async方法的调用会拆分为对MoveNext的调用
    • 用await看似是”等待“,经过编译后,其实没有等待
  • async背后线程切换
    • await调用的等待期间, .Net会把当前的线程返回给线程池,等异步方法调用执行完毕后,框架会从线程池再取出来一个线程执行后面的代码(存疑:和杨中科讲的不同,我自己测试了一下,执行异步方法的线程已经是新的线程,而这个新线程在执行完异步方法后,会接着执行后面的代码)
      • 不能保证再次使用的线程与之前线程是同一个线程
      • 但是如果异步方法执行时间很短,很有可能前后都是同一个线程

2.5 异步方法和多线程

  • 异步不等于多线程
  • 异步方法的代码并不会自动在新线程中执行,除非把手动代码放到新线程中执行
    • 例如使用 Task.Run(()=>{ … })来执行就可能使用一个新的线程

2.6 不使用async和await实现异步方法调用

  • 使用情况:在一个方法简单调用(没有复杂逻辑,而是转发调用一下)异步方法的时候可以省去写async和await

  • 如果本方法中不需要对返回结果做处理直接将Task返回给由需要结果值的上级调用者自己await,不做赚差价的中间商,提高效率

    • 对于方法A中调用异步方法B的传统写法

      public async Task Aasync(){
      	return await Basync();
      }
      
    • 对以上方法进行改造,以下代码是实现了同样的功能

      public Task Aasync(){
      	return Basync();
      }
      
    • 分析

      • 传统方式下await Basync()先是将int值取出,最后又封装成Task再返回
      • 简写之后,不用await就可以直接返回Task,这样就只是一个普通的方法调用(且这样运行效率更高,不会”拆了再装“)。这样就不会等了,程序执行到异步方法后会直接执行下一行代码。
    • 简写方式不适用的情况

      • 不是简单调用异步方法,而是对被调用异步方法的返回值处理后再返回,简写反而会更加麻烦

        public async Task Aasync(){
        	int res=awiat Basync();
        	return res+1;
        }
        //res被处理过,更适合用async、await写法
        
    • 总结:返回值为Task的不一定都要标注async,标注了async只是让我们可以更加方便的await而已

2.7 Task.Delay()

  • 如果想在异步方法中暂停一段时间,不要用Thread.Sleep(),因为它会阻塞调用线程,而要用await Task.Delay()

2.8 CancellationToken

  • CancellationToken使用场景:当需要提前终止任务时(例如,请求超时或用户取消请求),利用CancellationToken可获得提前终止执行的信号。

    • 例如下载资源时,用户跳转的其他网页,但是服务器仍会执行任务,用CancellationToken便可以识别下载任务是否取消,这样可以节约服务器资源
  • CancellationToken是结构体,包含如下成员

    • None :空

    • bool isCancellationRequested 是否取消请求

      //在请求方法中,用于判断
      async Task Dowmload()
      {
      	请求代码。。。
      	if(CancellationToken.isCancellationRequested ){
      		执行请求被取消后的代码
      	}
      }
      
    • Register(Action callback) (不常用) 注册取消监听

    • ThrowIfCancellationRequested() 如果任务被取消,执行到这句话就会抛异常

      //在请求方法中,如果取消了请求,就会抛出异常(需要处理异常,下面代码为了直观不处理了)
      async Task Dowmload()
      {
      	请求代码。。。
      	CancellationToken.ThrowIfCancellationRequested();
      }
      
  • 调用CancellationToken

    • 一般通过CancellationTokenSource来创建CancellationToken

      CancellationTokenSource cts=new CancellationTokenSource();
      //设置超时3s取消请求
      cts.CancelAfter(3000);
      //获取CancellationToken对象
      CancellationToken ct=CancellationTokenSource.Token;
      
      //在方法中传入CancellationToken对象,一旦方法执行超过3s,就会取消执行
      Dowmload(ct)
      
    • CancellationTokenSource包含的重要成员有:

      • CancelAfter() 超时后发出取消信号
      • Cancel() 发出取消信号
      • CancellationToken Token
  • 对与系统写好的方法,如果有CancellationToken 参数,那么调用这个方式时尽量把CancellationToken 传进去,“能转发CancellationToken 就转发”

    • 如果是自己写CancellationToken ,识别到任务取消后,我们还得去取消执行
    • 如果是调用系统的方法,一般都是识别、执行都写好的
  • 对于asp.net core的action,都可以传CancellationToken 作为参数,asp.net core框架会自动赋值

2.9 WhenAll()

  • WhenAll(): 用于等待多个Task执行结束,但不关心顺序
  • WhenAny(): 任何一个Task完成,这个Task就完成了

2.10 异步的其他知识点

  • 接口中的异步方法不需要写 async

  • 异步与yield

    • yield return :可以实现数据处理流水话,提升性能

    • //如代码
      fun(){
          List list=new List();
          list.add("abc");
          list.add("def");
          list.add("ghi");
          return list;
      }
      //用yield return 可以实现一样的效果
      fun(){
      yield return "abc";
      yield return "def";
      yield return "ghi";
      }
      
      
    • 在C#8.0之前 async方法中不能用和yield,而从8.0开始,将返回值声明为IAsyncEnumerable即可(不写Task)

      async IAsyncEnumerable test()
      {
          yield return "abc";
          yield return "def";
          yield return "ghi";
      }
      

3. lambda与LINQ

4. 依赖注入 DI

5. 配置系统 Configuration

6. 日志 Logging

你可能感兴趣的:(asp.net,笔记,c#)