对Asp.net WebApi中异步(async+await)接口实际使用及相关思考(示例给出了get,post,提交文件,异步接口等实践).
【很多初学者的疑问】
为何作为web api这样的天然的并发应用,还需要在controller的action上声明使用async这些呢?
<参考解答>
在 web 服务器上,.NET Framework 维护用于处理 ASP.NET 请求的线程池。 当请求到达时,将调度池中的线程以处理该请求。 如果以同步方式处理请求,则处理请求的线程将在处理请求时处于繁忙状态,并且该线程无法处理其他请求。
如果请求发出需要两秒钟时间才能完成的 web 服务调用,则该请求将需要两秒钟,无论是同步执行还是异步执行。 但是,在异步调用期间,线程在等待第一个请求完成时不会被阻止响应其他请求。 因此,当有多个并发请求调用长时间运行的操作时,异步请求会阻止请求队列和线程池的增长。
[注]总的来说,对单个客户端请求来说,它感受到的速度,响应时间并没有因为使用异步而提升,但对整个服务器来说,因为线程在异步场景下等待的同时还在服务其它的线程,因此线程数不会增长太快,进而不会轻易达到繁忙状态。
【给出一个自己写的分析代码】
using ConfigLab.Comp;
using ConfigLab.Comp.HttpRequestTools.HttpClient;
using ConfigLab.Comp.MetaData;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Hosting;
using System.Web.Http; namespace ConfigLab.WebApiProject.Controllers
{
/// <summary>
/// 功能简介:web api中的异步接口体会
/// 创建时间:2020-8-23
/// 创建人:pcw
/// 备注:如果不需要所有接口有一个默认的 /api/*中的api这段,需要自行修改RouteConfig.cs中的路由设置
/// </summary>
public class CommonAPIController : ApiController
{
/// <summary>
/// https://localhost:44305/CommonAPI/getTest1?userid=u001
/// </summary>
/// <param name="userid"></param>
/// <returns></returns>
public string getTest(string userid)
{
return $"test1_result(from web api):userid={userid}";
}
/// <summary>
/// https://localhost:44305/CommonAPI/getTest2
/// 参数:userid=u002&optype=add
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost]
public string postTest([FromBody] userActin data)
{
return $"test2_result(from web api):userid={data.userid},optype={data.optype}";
}
/// <summary>
/// 请求地址:https://localhost:44305/CommonAPI/postListByAsync
/// 参数:userid=u002&optype=add
/// 返回:多个网站的返回值
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<List<ResponseResult>> postListByAsync([FromBody] userActin data)
{
List<ResponseResult> listResult = new List<ResponseResult>();
HttpClientAssisterAsync httpAssist = new HttpClientAssisterAsync();//介绍(https://www.cnblogs.com/taohuadaozhu/p/13548266.html),Nuget 搜索安装: ConfigLab.Comp即可使用
Task<ResponseResult> tsk_rrs = httpAssist.SendRequestByGet("http://www.baidu.com");
await tsk_rrs;
listResult.Add(tsk_rrs.Result);
tsk_rrs = httpAssist.SendRequestByGet("http://www.ifeng.com");
await tsk_rrs;
listResult.Add(tsk_rrs.Result);
return listResult;
}
/// <summary>
/// 请求地址:https://localhost:44305/CommonAPI/SaveFile?projectId=p001&userid=u003
/// 附加参数:文件流
/// </summary>
/// <param name="projectId"></param>
/// <param name="userid"></param>
/// <returns></returns>
public async Task<RunResult> SaveFile(string projectId, string userid)
{
RunResult rrs = new RunResult();
if (!Request.Content.IsMimeMultipartContent())
{
//throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
return new RunResult() { RunCode = -1, RunMsg = "HttpStatusCode.UnsupportedMediaType" };
}
//string root = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["FileStorePath"]), DateTime.Now.ToShortDateString(), projectId);
string root = Path.Combine(ConfigurationManager.AppSettings["FileStorePath"], DateTime.Now.ToShortDateString(), projectId);
if (!Directory.Exists(root)) Directory.CreateDirectory(root);
MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(root);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
return new RunResult() { RunCode = 0, RunMsg = "" };
}
catch (Exception ex)
{
rrs.RunCode = -2;
rrs.RunMsg = $"获取客户端上传的文件流失败,ex.msg={ex.Message},ex.stacktrace={ex.StackTrace}";
}
return rrs;
}
}
/// <summary>
/// 测试用的post参数对象
/// </summary>
public class userActin
{
public string userid { get; set; }
public string optype { get; set; } }
}
对Asp.net WebApi中异步(async+await)接口实际使用及相关思考(示例给出了get,post,提交文件,异步接口等实践).的更多相关文章
- asp.net webform中使用async,await实现异步操作
摘要 最近想着将项目中的部分耗时的操作,进行异步化.就自己弄个demo进行学习.只需下面几个步骤就可以将aspx页面中注册异步操作. demo 比如我们需要抓取某个url的内容,这个时候我们可能会有下 ...
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异步
在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去 ...
- .NET4.0中使用4.5中的 async/await 功能实现异步
在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去 ...
- 关于ASP.NET WebAPI中HTTP模型的相关思考
对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.net remoting,MSMQ,WCF等等技术.对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯 ...
- 浅谈C#中的 async await 以及对线程相关知识的复习
C#5.0以后新增了一个语法糖,那就是异步方法async await,之前对线程,进程方面的知识有过较为深入的学习,大概知道这个概念,我的项目中实际用到C#异步编程的场景比较少,就算要用到一般也感觉T ...
- 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。
[TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...
- 在Silverlight中使用async/await
现在 async/await 大行其道,确实,有了 async/await ,异步编程真是简单多了,个人觉得 async/await 的出现,给开发者还来的方便,绝不亚于当年 linq 的出现. 但要 ...
- 在现有代码中通过async/await实现并行
在现有代码中通过async/await实现并行 一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色 ...
- 异步async/await简单应用与探究
感谢Marco CAO指出的两点错误,已做出修改与补充 异步函数(async/await)简单应用 .NET Framework4.5提供了针对异步函数语法糖,简化了编写异步函数的复杂度. 下面通过一 ...
- 理解ES7中的async/await
理解ES7中的async/await 优势是:就是解决多层异步回调的嵌套 从字面上理解 async/await, async是 "异步"的含义,await可以认为是 async w ...
随机推荐
- 没有使用IaC的DevOps系统都是耍流氓
作为现代软件工程的基础实践,基础设施即代码(Infrastructure as Code, IaC)是云原生.容器.微服务以及DevOps背后的底层逻辑.应该说,以上所有这些技术或者实践都是以基础设施 ...
- gets,fgets,puts,fputs,scanf,printf的作用,联系和区别
转载: https://blog.csdn.net/lc10915819/article/details/12747943
- Java学习之路:快捷键
常用的快捷键 Ctrl+Shift:切换输入法 Ctrl+C:复制 Ctrl+V:粘贴 Ctrl+X:剪切 Ctrl+A:全选 Ctrl+Z:撤销 Ctrl+Y:返回撤销 Ctrl+S:保存 Shif ...
- Vue学习之--------组件的基本使用(非单文件组件)(代码实现)(2022/7/22)
文章目录 1.为啥要使用组件 2.基本使用 3.代码实例 4.测试效果 5.注意点 1.为啥要使用组件 好用啊.像堆积木一样 2.基本使用 Vue中使用组件的三大步骤: 一.定义组件(创建组件) 二. ...
- Vue学习之--------Vue中收集表单数据(使用v-model 实现双向数据绑定、代码实现)(2022/7/18)
文章目录 1.Vue中实现表单数据的收集 1.1 基础知识 1.2 代码实例 1.3 测试效果 1.4 额外插一嘴 1.Vue中实现表单数据的收集 1.1 基础知识 表单中常用的标签:input(输入 ...
- 日志处理logging
前言 什么是日志?有什么作用?日志是跟踪软件运行时所发生的事件的一种方法,简单来说它可以记录某时某刻运行了什么代码,当出现问题时可以方便我们进行定位. 由python内置了一个logging模块,用户 ...
- 使用LEFT JOIN 统计左右存在的数据
最近做了一个数据模块的统计,统计企业收款.发票相关的数据,开始统计是比较简单,后面再拆分账套统计就有点小复杂,本文做一个简单的记录. 需求 企业表 企业表t_company有如下字段:标识id.企业名 ...
- Sentinel 介绍与下载使用
sentinel 前方参考 计算QPS-Sentinel限流算法 https://www.cnblogs.com/yizhiamumu/p/16819497.html Sentinel 介绍与下载使用 ...
- 7.websocket收发消息
客户端主动向服务端发起websocket连接,服务端接收到连接后通过(握手) 客户端 websocket socket = new WebSocket('ws://127.0.0.1/ws/'); 服 ...
- vue2 解决跨域
vue2.x 解决跨域 通过devServer将接口代理到本地在开发的时候,需要请求同局域网内的接口,发现直接使用http://对方的ip地址/接口路径,会出现类似下图的跨域报错 找到并打开vue.c ...