EF学习笔记:异步处理和存储过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF学习笔记:异步处理和存储过程相关的知识,希望对你有一定的参考价值。

总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

上一篇:EF学习笔记(八):更新关联数据

本篇原文:Async and Stored Procedures

为何要采用异步?

一个Web服务器肯定有可用线程的限制,那么在一些访问量特别大的情况下,线程肯定会消耗完;这个时候服务器肯定处理不了请求,必须等线程里处理结束才可以处理请求;

在非异步的时候,很多线程都处于等待状态,并不是一直在工作,而是在等类似于I/O等处理结束;

采用异步的时候,当一个处理在等待I/O处理结束的时候,可以先去做做其他事情;

所以异步处理可以使服务器更为高效,较低延迟的情况下处理更多的请求。

在早期的.NET中,写或者测试异步处理都是很复杂的,庆幸的是.NET 4.5以后写或者测试异步处理请求代码都非常简单,除非有特别的理由不采用异步处理;

异步处理确实会有一些多出来的系统开销,对于低流量的应用,效果可以忽略,但对于大流量的应用,效果是很明显的;

更专业的资料: Use .NET 4.5‘s async support to avoid blocking calls.

下面做些代码测试:

采用异步方式新建Department控制器:

 技术分享

自动生成的Index Action:

  public async Task<ActionResult> Index()
        {
            var departments = db.Departments.Include(d => d.Administrator);
            return View(await departments.ToListAsync());
        }

与非异步方式,有4处不同来实现EF异步请求数据:

1、请求方法加上了async标志关键字,等于告诉编译器这个方法中有部分方法体为异步的,需要生成针对部分方法体的异步回调,并且自动创建一个Task<ActionResult>对象作为异步返回;

2、返回类型从ActionResult变为Task<ActionResult>,Task<T>表明后续处理将使用T类型;

3、await关键字引用于Call Web Service,当编译器看到await这个关键字,就会把这个方法分为两部分,第1部分就是开始异步处理,第2部分就是异步处理完成后,再回调的部分;

4、采用ToList的异步版本方法;

(原文后面一段没看明白。。。感觉有些笔误以及思路没理清楚)

接后面改几个视图,把Index视图里稍微改下,显示Administrator的全名:

@model IEnumerable<EFTest.Models.Department>

@{
    ViewBag.Title = "Departments";
}

<h2>Departments</h2>

<p>
    @html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>        
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Budget)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StartDate)
        </th>
        <th>
            Administrator
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>        
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Budget)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.StartDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Administrator.FullName)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.DepartmentID }) |
            @Html.ActionLink("Details", "Details", new { id=item.DepartmentID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.DepartmentID })
        </td>
    </tr>
}

</table>

把Create\\Edit视图中 InstructorID 字段标题 改为 Administrator ,把原来一行注释掉,增加一行:

     <div class="form-group">
            <label class="control-label col-md-2" for="InstructorID">Administrator</label>
            @*@Html.LabelFor(model => model.InstructorID, "InstructorID", htmlAttributes: new { @class = "control-label col-md-2" })*@
            <div class="col-md-10">
                @Html.DropDownList("InstructorID", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.InstructorID, "", new { @class = "text-danger" })
            </div>
        </div>
@model EFTest.Models.Department

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Department</h4>
    <hr />
    <dl class="dl-horizontal">
        @*<dt>
            @Html.DisplayNameFor(model => model.Administrator.LastName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Administrator.LastName)
        </dd>*@
        <dt>
            Administrator
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Administrator.FullName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Name)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Budget)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Budget)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.StartDate)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StartDate)
        </dd>

    </dl>

    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()

        <div class="form-actions no-color">
            <input type="submit" value="Delete" class="btn btn-default" /> |
            @Html.ActionLink("Back to List", "Index")
        </div>
    }
</div>

Delete\\Detail如上面修改方法;

效果:

技术分享

技术分享

看起来的效果和其他控制器一样。。。但这个控制器后台查询处理数据都是异步方式。

对于异步方式,有两点需要注意:

1、异步方式无法线程安全,换句话说,不要尝试同一个上下文实例来并行多次处理;

2、如果你要享受到异步方式的好处,记得所有使用到的并且涉及到数据库操作的类库(例如:分页)都需要采用异步方式;

 





以上是关于EF学习笔记:异步处理和存储过程的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL进阶学习笔记四:MySQL存储过程之定义条件,处理过程及存储过程的管理!(视频序号:进阶_11,12)

EF6学习笔记

java 登录过程 - android片段,异步任务登录,Asp.net控制器,存储库

《javascript高级程序设计》学习笔记 | 11.1.异步编程

简单的分布页+登录+EF调用存储过程

EF 存储过程(下)