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

  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/jf-ace/p/14655880.html
Copyright © 2011-2022 走看看