前言

有些问题只有真正遇到或者用到并且多加思考才会想到,平常若作为自学的心态去学习则不会考虑太多,我慢慢明白对于那些有太多要学的东西或者说的更加明确而且具体一点的话,如果对于你现在不是迫切要学或者需要掌握的技能,那就暂且放在一边吧,比如现在比较火的angular和react,我之前也花时间去学了,但是公司压根不用或者有专门的前端你学多了貌似没什么很大的实际用途,其实仅仅做一点基本的了解即可,至少别人问起也知道一二,不要看到别人学什么或者火了什么就盲目跟风,还是根据自身实际情况来学习才是王道。这不刚说到根据自身来学习,脑袋妄想着正在做的项目,突然冒出一个想法,为什么那不可以,为什么它又存在呢?这篇文章就出来了。

话题介绍

我们知道在WebAPi中对于响应结果我们都是这样用的:

        public HttpResponseMessage GetResult<T>(T t)
{
return Request.CreateResponse<T>(HttpStatusCode.OK, t);
}

在项目中前端为了和其他统一,封装了一套响应的结果和状态码,要求直接返回对象,于是将上述修改成比如如下:

    public Result<List<Person>> GetResult()
{
var result = new Result<List<Person>>();
return result;
} public class Result<T> : BaseResult
{
public T Data;
} public class BaseResult
{
public string Message;
public int Status;
public ErrorCode ErrorCode;
} public enum ErrorCode
{
    ......
}

统观以上两种方法,一种是WebAPi内置响应的结果,另外一种则是直接返回自定义响应结果。

于是乎,我开始思索这两种方法虽然都能得到我们想要的结果,但是有什么区别没有呢?说的更加明确一点的是,二者在数据响应上有没有性能上的差异呢?

WebAPi响应结果和自定义响应结果二者性能差异

以上则是需要返回对象来进行处理,而有些我们则不需要返回任何对象来进行处理例如直接返回void,而在WebAPi中对应需要返回 IHttpActionResult 例如自定义返回则是如下:

   public void GetFirst()
{.....}

在WebAPi中则是进行如下返回:

   public IHttpActionResult GetSecond()
{
return OK();
}

下面我们在控制台中分别来测试这二者在WebHost以及在SelfHost上的差异,我们如何获取其差异呢?我们通过对void方法和http方法在控制台中发出1000个请求来获取其总共花费时间来进行比较。

SelfHost

       [HttpGet]
public void GetFirst()
{
StringBuilder stringbuilder = new StringBuilder();
for (int i = ; i < ; i++)
{
stringbuilder.Append("something");
}
} [HttpGet]
public IHttpActionResult GetSecond()
{
StringBuilder stringbuilder = new StringBuilder();
for (int i = ; i < ; i++)
{
stringbuilder.Append("something");
}
return Ok();
}

在控制台中方法如下:

        private const string voidUrl = "http://localhost:8080/api/home/GetFirst";
private const string httpUrl = "http://localhost:8080/api/home/GetSecond";
private static List<TimeSpan> voidTimes = new List<TimeSpan>();
private static List<TimeSpan> httpTimes = new List<TimeSpan>();
static void Main(string[] args)
{
Console.WriteLine("Start Test....");
for (int i = ; i < ; i++)
{
voidTimes.Add(getResponse(voidUrl));
Thread.Sleep();
Console.WriteLine("void Test " + i);
}
Console.WriteLine("Finished Void Test");
for (int i = ; i < ; i++)
{
httpTimes.Add(getResponse(httpUrl));
Thread.Sleep();
Console.WriteLine("http Test " + i);
}
Console.WriteLine("Finished Http Test");
var voidTotalTime = voidTimes.Sum(t => t.Milliseconds);
Console.WriteLine("void方法发出1000个请求总共需要时间:" + voidTotalTime);
Console.WriteLine("void方法平均每一个请求需要时间:" + voidTotalTime / 1000.00 + "秒"); var httpTotalTime = httpTimes.Sum(t => t.Milliseconds);
Console.WriteLine("http方法发出1000个请求总共需要时间: " + httpTotalTime);
Console.WriteLine("http方法平均每一个请求需要时间: " + httpTotalTime / 1000.00 + "秒"); Console.Read();
} static TimeSpan getResponse(string url)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(url);
var task = httpClient.GetAsync(httpClient.BaseAddress).Result;
var result = task.Content.ReadAsAsync(typeof(object));
var timeSpan = stopWatch.Elapsed;
stopWatch.Stop();
return timeSpan;
}

下面我们来直观演示整个过程:

从上看出似乎由http方法节约一点时间,我们将上述中的方法循环次数,进行如下修改:

            for (int i = ; i < ; i++)
{
stringbuilder.Append("something");
}

这时候我们再来看看结果:

当有二十万条数据时此时时间又多节约一点点。接下来我们再来测试WebHost。

WebHost

在WebHost中我们利用特性来管理请求方法:

        [HttpGet]
[Route("test/void")]
public void GetFirst()
{
StringBuilder stringbuilder = new StringBuilder();
for (int i = ; i < ; i++)
{
stringbuilder.Append("something");
}
} [HttpGet]
[Route("test/IHttpActionResult")]
public IHttpActionResult GetSecond()
{
StringBuilder stringbuilder = new StringBuilder();
for (int i = ; i < ; i++)
{
stringbuilder.Append("something");
}
return Ok();
}

此时将控制台请求地址进行对应修改即可:

 private const string voidUrl = "http://localhost:2531/test/void";
private const string httpUrl = "http://localhost:2531/test/IHttpActionResult";

此时演示结果如下:

此时快了接近一秒。此时我们将数据增加到同样20万时再看看:

此时还是快了1秒。到了这里是不是就算结束了呢,我们再来看看

当我们请求void方法时返回的状态码为如下:

此时利用http来进行响应则是如下:

其返回状态也不同,我们则需要有对应的处理方式。

总结

在演示void方法和http方法时有时也会出现http方法时间比void方法慢的原因,不知是何缘故,理论上来说用HttpResponseMessage来作为响应结果会快一点,因为HttpResponseMessage内置对于一些异常都做了处理并返回对应的状态码而void方法则未做任何处理。但是从另外一个角度看,若我们自定义一套返回的状态码来进行处理也并非不可,个人觉得利用WebAPi内置的HttpResponseMessage响应机制来进行结果响应最佳,期待各位的批评和答案,同时不知上述测试是否合理。当时想到这个问题时也查了相关资料,还真有做过类似测试的,于是借用了一下。

参考资料:http://stackoverflow.com/questions/22689888/webapi-2-is-a-void-response-faster-then-ihttpactionresult

WebAPi返回类型到底应该是什么才合适,这是个问题?的更多相关文章

  1. asp.net core系列 38 WebAPI 返回类型与响应格式--必备

    一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...

  2. WebApi返回类型设置为json的三种方法

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

  3. webapi 返回类型

    参考 大神;https://www.cnblogs.com/landeanfen/p/5501487.html

  4. webapi返回文件流

    逻辑说明 webapi返回类型为IHttpActionResult接口,内部方法返回HttpResponseMessage. public interface IHttpActionResult { ...

  5. QT5中编译存在的几个问题(LNK2019,构造函数不能有返回类型)

    1. 自己构造新类,注意必须在头文件最后加上分号 写个c++类报“构造函数不能有返回类型”, 谷歌一下,才找到原因: 原来是我定义的类后面没有用“:”结尾,构造函数默认把整个类作为返回值了 2. 新建 ...

  6. webapi的返回类型,webapi返回图片

    1.0 首先是返回常用的系统类型,当然这些返回方式不常用到.如:int,string,list,array等.这些类型直接返回即可. public List<string> Get() { ...

  7. 关于webapi 返回的类型的笔记

    经过测试发现使用IE浏览器返回的数据是json,而使用Firefox和Chrome返回的则为xml,经研究发现IE在发生http请求时请求头accpet节点相比Firefox和Chrome缺少&quo ...

  8. 【转载】C#.NET WebApi返回各种类型(图片/json数据/字符串),.net图片转二进制流或byte

    C#.NET WebApi返回各种类型(图片/json数据/字符串),.net图片转二进制流或byte 转载:http://www.itdos.com/Mvc/20150302/0741255.htm ...

  9. ASP.NET Core WebAPI控制器返回类型的最佳选项

    前言 从.NET Core 2.1版开始,到目前为止,控制器操作可以返回三种类型的WebApi响应.这三种类型都有自己的优点和缺点,但都缺乏满足REST和高可测性的选项. ASP.NET Core中可 ...

随机推荐

  1. Linux OpenVPN 服务端吊销(revoke)客户端证书

    (转自:https://www.xiaohui.com/dev/server/20070904-revoke-openvpn-client.htm) OpenVPN 服务器与 VPN 客户端之间的身份 ...

  2. jsp 中 有没有类似java if else语句

    <c:when test=""></c:when> <c:otherwise></c:otherwise> 有if else的功能 ...

  3. notepad++崩溃后文件内容变为NUL的解决方法

    毫无疑问,notepad++是一款非常优秀的文本编辑器,但是notepad++有时候会崩溃,之后文件内容就会全部变成NUL 当你打文件看到自己辛辛苦苦的成果全都变成NUL是不是有想哭的感觉?" ...

  4. 微信第三方平台定时接收component_verify_ticket

    背景: 获取第三方平台令牌(component_access_token),增加了component_verify_ticket参数.component_verify_ticket由公众平台每隔10分 ...

  5. java面向对象_构造器

    构造器(构造方法):是类中定义的方法. 1)常常用于给成员变量赋值: 2)与类同名,没有返回值类型,也不能写void: 3)在创建对象时被自动调用.所以构造方法的访问修饰符要用public,才能被自动 ...

  6. Android 中关于ListView分割线的设置

    今天发现许多App上的listview的item之间的分割线都只显示了右边一部分,而左边的那一半则没有,第一反应则是给分割线设置一张背景图片就ok了: android:divider="@m ...

  7. Proxy

    Proxy: Script: http://apgutmg01:8080/array.dll?Get.Routing.Script Server: apgutmg01 Port: 8080

  8. 基于struts2和hibernate的分页实现

    在拜读了各位大牛的博客后,加以修改和添加总算是借鉴出了一个可行的分页实现.(●'◡'●) 话不多说,先贴两张效果图吧 接下来是实现代码: pagingDAOImpl.java public class ...

  9. Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序

            1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...

  10. SQL Server 事件通知(Event notifications)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 事件通知监控DDL(NotifyQue ...