zoukankan      html  css  js  c++  java
  • 异步编程

    同步操作的情况是:用户发送请求给服务器,服务器收到请求到数据库中读取数据,数据返回服务器响应给用户。同步操作只能挨个进行而用户不可能只有一个。处理请求最消耗时间的事情就是IO操作(服务器等待数据库返回数据的时间),只有数据库返回数据时服务器才会把信息返回给用户,这样既浪费了用户的时间,服务器的利用率也及其低下。

    处理的办法有很多:可以在服务器上开启多进程,但是操作系统的进程开启数量是有限的,堆积过多会导致死锁现象发生。而单纯的靠买机器充当服务器不是很明智的做法,所以还是得利用异步节省IO操作的时间(不要等待数据库,继续执行下一个请求,当数据库返回数据以后,再回头继续处理上一个请求)。在互联网海量数据的加持下,仅仅用异步很容易达到服务器性能的天花板。所以对于请求数量极其大的情况下可以:多个机器+每个机器开启多进程+异步操作。

    C#中的异步操作:Async/await:

    异步方法:函数在执行完成前就可以先返回调用方,然后继续执行接下来的逻辑完成任务的函数;

    返回类型:void、Task、Task<T>、IAsyncEnumerable<T>(处理数据流)

    Async函数只能被Async函数调用;

    项目中的数据库操作都可以添加异步操作:

    添加资源和删除资源不需要改变:文章后面会说到。

    数据仓储接口中的函数:

     实现数据仓储接口中的函数:

    Controller:

    为什么添加资源和删除资源不需要添加异步:

    目前使用的orm框架是entity framework core,在旧版的ef框架中add添加与remove删除都没有对应的异步接口,也就是说没有AddAsync与RemoveAsync。

    不过,自从ef6开始,数据的添加操作也有异步操作了,AddAsync函数也有了,我们使用的ef是最新版,所以add添加也将会支持异步操作,接下来的课程都会支持add与delete的异步操作。

    下面简单聊一下为什么没有remove的异步操作。

    • 与数据库的读取数据操作不一样(比如GetTouristRoutesAsync函数),不管是add还是remove都不会在被调用后直接向数据库写入数据,而是先把数据放在DbContext中,由一个叫做“ChangeTracker”的东西管理(暂时理解为内存),直到调用 _context.SaveChangesAsync()以后,数据才会被真正写入数据库中。

      数据存入ChangeTracker(DbContext)的时候进行的是内存操作,并不是真正的IO操作,所有没有必要进行异步操作,这就是为什么add与delete不需要对应的异步函数。

    那么,为什么最新版的ef又提供了add的异步操作AddAsync呢?

    • 因为,有时候在添加数据的时候,可能会需要与数据库提前沟通一下,比如说如果一个模型的主键id,是整数类型、而且是由数据库控制的自增数字,那么我们在添加数据的时候必须得先问问数据库这个新数据的id是什么啊,得到id以后再把数据存入ChangeTracker里面,最后,直到调用 _context.SaveChangesAsync()以后,数据才会被真正写入数据库中。而问数据库取得id的过程实际上就是一个IO操作,既然是IO,那么异步操作就在所难免了,这就是为什么新版的ef加入了AddAsync这个函数,提供了这个异步操作。

    更详细的异步操作及原理:https://www.cnblogs.com/liqingwen/p/5844095.html

  • 相关阅读:
    PHP函数之array_chunk
    C#常用的数据结构
    SQLServer锁和并发控制
    数据库堵塞和死锁详解
    SQLServer事务隔离级别
    HTML5 Canvas 为网页添加文字水印
    浏览器记住密码的自动填充Input问题完美解决方案
    C#队列Queue实现一个简单的电商网站秒杀程序
    C# 递归省市区三级树结构
    System.InvalidOperationException:“线程间操作无效: 从不是创建控件“txtPortName02”的线程访问它。”
  • 原文地址:https://www.cnblogs.com/jf-ace/p/14655880.html
Copyright © 2011-2022 走看看