【很多初学者的疑问】

为何作为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; } }
}

最新文章

  1. 为什么要使用Mac系统?
  2. C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)
  3. 多线程BackgroundWorker
  4. 在服务器上远程链接另一台服务器的数据库的方法how to connet the database from the other host
  5. OpenStack手动从数据库中删除实例 - ugyn109的专栏 - 博客频道 - CSDN.NET
  6. yii2-datepicker/datetimepicker插件使用
  7. some windowsphone templates
  8. Servlet获取当前服务器的实际路径
  9. [HDOJ4738]Caocao&#39;s Bridges(双联通分量,割边,tarjan)
  10. git push 报错
  11. Hibernate + MySQL中文乱码问题
  12. Android自定义Activity酷炫的动画跳转效果
  13. MVC 插件化框架支持原生MVC的Area和路由特性
  14. android中edittext被键盘挡住问题
  15. maven项目添加websocket
  16. Intellij Idea web项目的部署配置[转]
  17. 为测试赋能,腾讯WeTest探索手游AI自动化测试之路
  18. bat脚本:Java一键编译(Javac java)
  19. 推荐算法之用户推荐(UserCF)和物品推荐(ItemCF)对比
  20. 编译安装LAMP

热门文章

  1. flinksql读写redis
  2. ExceptionHandler配合RestControllerAdvice全局处理异常
  3. 测试开发HTTP请求过程(一)
  4. .NET Core C#系列之XiaoFeng.Data.IQueryableX ORM框架
  5. 0基础90分钟会用PS——GenJi笔记
  6. JK触发器与模12计数器
  7. JVM学习笔记——垃圾回收篇
  8. 说说switch关键字
  9. 关于Redis的,你了解多少?来看看我的笔记
  10. Java-数组工具类Arrays