设为首页 加入收藏

TOP

ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await(一)
2019-09-17 15:34:41 】 浏览:30
Tags:ASP.NET Core Web 应用程序 系列 异步 编程 async await

PS:异步编程的本质就是新开任务线程来处理。

约定:异步的方法名均以Async结尾。

实际上呢,异步编程就是通过Task.Run()来实现的。

了解线程的人都知道,新开一个线程来处理事务这个很常见,但是在以往是没办法接收线程里面返回的值的。所以这时候就该await出场了,await从字面意思不难理解,就是等待的意思。

执行await的方法必须是async修饰的,并且是Task的类型。 异步执行后,返回的信息存储在result属性中。但并非主进程就会卡在await行的代码上,执行到await方法之后主线程继续往下执行,无需等待新的线程执行完再继续。只有当需要用到新线程返回的result结果时,此时主进程才会等待新线程执行完并返回内容。也就是说,若无需用到新线程返回的结果,那么主进程不会等待。

async和await呢,返回类型就3种:void、Task、Task<TResult>。

1、void

如果在触发后,你懒得管,请使用 void。

void返回类型主要用在事件处理程序中,一种称为“fire and forget”(触发并忘记)的活动的方法。除了它之外,我们都应该尽可能是用Task,作为我们异步方法的返回值。

返回void,意味着不能await该异步方法,即可能出现线程阻塞,并且也无法获取exception抛出的异常,通常这些异常会导致我们的程序失败,如果你使用的是Task和Task<TResult>,catch到的异常会包装在属性里面,调用方法就可以从中获取异常信息,并选择正确的处理方式。

2、Task

你如果只是想知道执行的状态,而不需要一个具体的返回结果时,请使用Task。
与void对比呢,Task可以使用await进行等待新线程执行完毕。而void不需要等待。

3、Task<TResult> 

当你添加async关键字后,需要返回一个将用于后续操作的对象,请使用Task<TResult>。

主要有两种方式获取结果值,一个是使用Result属性,一个是使用await。他们的区别在于:如果你使用的是Result,它带有阻塞性,即在任务完成之前进行访问读取它,当前处于活动状态的线程都会出现阻塞的情形,一直到结果值可用。所以,在绝大多数情况下,除非你有绝对的理由告诉自己,否则都应该使用await,而不是属性Result来读取结果值。

 

接下来我们来看个例子,在上一章的基础上我们添加异步的方法。

首先是仓储层接口:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

using TianYa.DotNetShare.Model;

namespace TianYa.DotNetShare.Repository
{
    /// <summary>
    /// 学生类仓储层接口
    /// </summary>
    public interface IStudentRepository
    {
        /// <summary>
        /// 根据学号获取学生信息
        /// </summary>
        /// <param name="stuNo">学号</param>
        /// <returns>学生信息</returns>
        Student GetStuInfo(string stuNo);

        /// <summary>
        /// 根据学号获取学生信息(异步)
        /// </summary>
        /// <param name="stuNo">学号</param>
        /// <returns>学生信息</returns>
        Task<Student> GetStuInfoAsync(string stuNo);
    }
}

接着是仓储层实现:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

using TianYa.DotNetShare.Model;

namespace TianYa.DotNetShare.Repository.Impl
{
    /// <summary>
    /// 学生类仓储层
    /// </summary>
    public class StudentRepository : IStudentRepository
    {
        /// <summary>
        /// 根据学号获取学生信息
        /// </summary>
        /// <param name="stuNo">学号</param>
        /// <returns>学生信息</returns>
        public Student GetStuInfo(string stuNo)
        {
            //数据访问逻辑,此处为了演示就简单些
            var student = new Student();
            switch (stuNo)
            {
                case "10000":
                    student = new Student() { StuNo = "10000", Name = "张三", Sex = "", Age = 20 };
                    break;
                case "10001":
                    student = new Student() { StuNo = "10001", Name = "钱七七", Sex = "", Age = 18 };
                    break;
                case "10002":
                    student = new Student() { StuNo = "10002", Name = "李四", Sex = "", Age = 21 };
                    break;
                default:
                    student = new Student() { StuNo = "10003", Name = "王五", Sex = "", Age = 25 };
                    break;
            }

            return student;
        }

        /// <summary>
        /// 根据学号获取学生信息(异步)
        /// </summary>
        /// <param name="stuNo">学号</param>
        /// <returns>学生信息</returns>
        public virtual async Task<Student> GetStuInfoAsy
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇NOPI 读与写 下一篇Entity Framework 6.0 入门系列 ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目