await关键字对于方法执行的影响

将上一篇WebApi上传图片中代码修改(使用了await关键字)如下:

        [HttpPost]
public async Task<string> Post()
{
if (!Request.Content.IsMimeMultipartContent())
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Invalid Request!"));
//获取学员信息
Student model = new Student()
{
Name = HttpContext.Current.Request.Form["StuName"],
GroupName = HttpContext.Current.Request.Form["GroupName"],
// ...
};
//获取学员通过科目名称
string passSubject = HttpContext.Current.Request.Form["passSubject"];
//获取学员未通过科目名称
string noPassSubject = HttpContext.Current.Request.Form["passSubject"];
Trace.WriteLine("begin 添加学员信息");
//添加学员信息
await stuService.AddStuByAsync(model).ContinueWith(p =>
{
long stuId = p.Result;
Trace.WriteLine("begin 通过科目表");
subjectService.AddPassSubject(passSubject, stuId);//添加此学员通过科目信息
Trace.WriteLine("end 通过科目表"); Trace.WriteLine("begin 未通过科目表");
subjectService.AddNoPassSubject(noPassSubject, stuId);//添加此学员未通过科目信息
Trace.WriteLine("end 未通过科目表");
});
Trace.WriteLine("end 添加学员信息");
string path = System.Web.HttpContext.Current.Server.MapPath("~/Images/upload/");
Trace.WriteLine("获取图片......");
Request.Content.ReadAsMultipartAsync().ContinueWith(p =>
{
var content = p.Result.Contents;
Trace.WriteLine("begin 图片");
foreach (var item in content)
{
if (string.IsNullOrEmpty(item.Headers.ContentDisposition.FileName))
{
continue;
}
item.ReadAsStreamAsync().ContinueWith(a =>
{
Stream stream = a.Result;
string fileName = item.Headers.ContentDisposition.FileName;
fileName = fileName.Substring(, fileName.Length - ); Trace.WriteLine("图片名称:" + fileName); //stream 转为 image
saveImg(path, stream, fileName);
});
}
Trace.WriteLine("end 图片");
});
return "ok";
}

结果:

未加await  主线程和ContinueWith 里的子

线程都在执行

加了await  主线程会等待ContinueWith 里的子

线程

 
通过对比可以看出,加了await后,当方法执行到await这里,没有继续向下执行,而是等待await 后的方法执行完成后才继续向下执行。

也就是说遇到await时,当前线程会暂时停止,去等待await 后的方法执行完成。


添加一个新的方法 AddPassSubjectByAsync 此方法内没有使用到 await

 
 
添加学员信息的代码修改如下:
  Trace.WriteLine("begin 添加学员信息");
//添加学员信息
stuService.AddStuByAsync(model).ContinueWith(async p =>
{
Trace.WriteLine("begin 子线程2");
long stuId = p.Result;
subjectService.AddPassSubjectByAsync(passSubject, stuId).ContinueWith(a =>
{
Trace.WriteLine("子线程3");
});
Trace.WriteLine("end 子线程2");
});
Trace.WriteLine("end 添加学员信息");

运行结果:

可以看出子线程3运行的时候,子线程2和主线程也是在运行着。

那么接下来就是问题所在,如果子线程2中有await关键字,各个线程执行状态如何呢?

例1:

只有子线程中存在await,代码如下:

  Trace.WriteLine("begin 添加学员信息");
//添加学员信息
stuService.AddStuByAsync(model).ContinueWith(async p =>
{
Trace.WriteLine("begin 子线程2");
long stuId = p.Result;
await subjectService.AddPassSubjectByAsync(passSubject, stuId).ContinueWith(a =>
{
Trace.WriteLine("begin 子线程3");
Trace.WriteLine("begin 未通过科目表");
subjectService.AddNoPassSubject(noPassSubject, stuId);
Trace.WriteLine("end 未通过科目表");
Trace.WriteLine("end 子线程3");
});
Trace.WriteLine("end 子线程2");
});
Trace.WriteLine("end 添加学员信息");
//测试线程3执行时主线程是否执行
Trace.WriteLine("begin 测试");
subjectService.GetSubjectList();//获取所有的科目信息
Trace.WriteLine("end 测试");

结果:

通过前四行可看出主线程和子线程2都在执行。当子线程2执行到await 处,子线程2变为"暂停"状态,去执行子线程3,这时候主线程和子线程3在执行中 ( 从子线程3还未end,主线程已经开始执行测试可看出 )。

当子线程3执行完,子线程2从"暂停"状态唤醒,继续向下执行。

说明子线程2、3的执行状态并没有影响主线程。

例2:

都有await,代码如下:

   Trace.WriteLine("begin 添加学员信息");
//添加学员信息
await stuService.AddStuByAsync(model).ContinueWith(async p =>
{
Trace.WriteLine("begin 子线程2");
long stuId = p.Result;
await subjectService.AddPassSubjectByAsync(passSubject, stuId).ContinueWith(a =>
{
Trace.WriteLine("begin 子线程3");
Trace.WriteLine("begin 未通过科目表");
subjectService.AddNoPassSubject(noPassSubject, stuId);
Trace.WriteLine("end 未通过科目表");
Trace.WriteLine("end 子线程3");
});
Trace.WriteLine("end 子线程2");
});
Trace.WriteLine("end 添加学员信息");
//测试线程3执行时主线程是否执行
Trace.WriteLine("begin 测试");
subjectService.GetSubjectList();//获取所有的科目信息
Trace.WriteLine("end 测试");

结果:

通过输出的前两行可看出,主线程运行到await 处的时候,主线程 "暂停" ,等待子线程2返回结果。此时子线程2开始执行,同样运行到await 处的时候,子线程2 "暂停",

通过输出信息可看出子线程3执行时主线程会被"唤醒"( 这时子线程3和主线程都在执行中 )。当子线程3执行完成后,子线程2继续执行。

说明:当方法中遇到await关键字的时候,程序执行可分为两个部分。

1. 当前线程"暂停" ,去执行await后的方法( 如子线程2 )。

2. 如果主线程"暂停"状态时,主线程会被"唤醒"( 此时会有两个线程在执行,如主线程和子线程3 )。

 

WebApi上传图片 await关键字的更多相关文章

  1. kindeditor修改图片上传路径-使用webapi上传图片到图片服务器

    kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 在这里我着重介绍一些使用kindeditor修改图片上传路径并通过webapi上传图片到图片服务器的方案. 因为我使用的 ...

  2. kindeditor扩展粘贴图片功能&修改图片上传路径并通过webapi上传图片到图片服务器

    前言 kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 而kindeditor却对图片的处理不够理想. 本篇博文需要解决的问题有两个: kindeditor扩展粘贴图片功 ...

  3. kindeditor扩展粘贴截图功能&修改图片上传路径并通过webapi上传图片到图片服务器

    前言 kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 而kindeditor却对图片的处理不够理想. 本篇博文需要解决的问题有两个: kindeditor扩展粘贴图片功 ...

  4. Asp.Net WebApi上传图片

    webapi using System; using System.Collections; using System.Collections.Generic; using System.Diagno ...

  5. 浅谈async、await关键字 => 深谈async、await关键字

    前言 之前写过有关异步的文章,对这方面一直比较弱,感觉还是不太理解,于是会花点时间去好好学习这一块,我们由浅入深,文中若有叙述不稳妥之处,还请批评指正. 话题 (1)是不是将方法用async关键字标识 ...

  6. 异步编程,采用WorkgroupWorker,async和await关键字

    金科玉律:不要在UI线程上执行耗时的操作:不要在除了UI线程之外的其他线程上访问UI控件! NET1.1的BeginInvoke异步调用,需要准备3个方法:功能方法GetWebsiteLength,结 ...

  7. 多线线程async与await关键字

    创建线程 //这里面需要注意的是,创建Thread的实例之后,需要手动调用它的Start方法将其启动. //但是对于Task来说,StartNew和Run的同时,既会创建新的线程,并且会立即启动它. ...

  8. Async 与 Await 关键字研究

    1        Aynsc 和 Await 关键字的研究 在 .NET 4.0 以后,基于 Task 的异步编程模式大行其道,因其大大简化了异步编程所带来的大量代码工作而深受编程人员的欢迎,如果你曾 ...

  9. async和await关键字实现异步编程

    async和await关键字实现异步编程 异步编程   概念 异步编程核心为异步操作,该操作一旦启动将在一段时间内完成.所谓异步,关键是实现了两点:(1)正在执行的此操作,不会阻塞原来的线程(2)一旦 ...

随机推荐

  1. LED驅動電路概述

    LED是一種固體光源,當它兩端加上正向電壓,半導體中的少數載流子和多數載流子發生復合,放出的過剩能量將引起光子發射.采用不同的材料,可制成不同顏色有 發光二極管 . 隨著對LED研究的進一步深入,其光 ...

  2. HDOJ 1202 The calculation of GPA

    Problem Description 每学期的期末,大家都会忙于计算自己的平均成绩,这个成绩对于评奖学金是直接有关的.国外大学都是计算GPA(grade point average) 又称GPR(g ...

  3. Linux中断分层技术

    一.中断嵌套  当系统正在执行某中断处理函数时,又产生了一个新的中断,这就叫做中断嵌套.当中断为慢速中断时,新的中断会取代当前中断,即当前中断没有执行完就结束 了:当中断为快速中断时,新的终端就不会产 ...

  4. JAVA 并发实现六(Volatile的使用)

    Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量. 这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低 ...

  5. 深入浅出-iOS函数式编程的实现 && 响应式编程概念

    简介 本篇主要回顾一下--iOS函数式编程 && 响应式编程概念 ,如何一步步实现函数式编程的过程,对阅读Masonry && SnapKit源码有一定的帮助. 配图 ...

  6. 微信中web页面实现和公众号中查看图片一样的效果

    最近开发了一套资讯相关的web页面,嵌套在微信中,可支持点赞.评论等...在文章详情中,图片需要点击放大,随手势放大缩小,左右可滑动切换,总之类似于微信公众号效果. 开始想的方案是用轮播插件.或者在i ...

  7. Collision使用 获取其组件执行变色操作

    using UnityEngine; using System.Collections; public class CyCollision : MonoBehaviour { void OnColli ...

  8. 【C#网络基础】C# get post请求

    using KTCommon.Helper; using KTCommon.LOG; using System; using System.Collections.Generic; using Sys ...

  9. Hadoop 类Grep源代码注释

    /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agree ...

  10. cdh4.1.2 hadoop和oozie集成问题

    1.异常信息例如以下: Caused by: com.google.protobuf.ServiceException: java.net.ConnectException: Call From sl ...