WebAPi返回类型到底应该是什么才合适,这是个问题?

前言

有些问题只有真正遇到或者用到并且多加思考才会想到,平常若作为自学的心态去学习则不会考虑太多,我慢慢明白对于那些有太多要学的东西或者说的更加明确而且具体一点的话,如果对于你现在不是迫切要学或者需要掌握的技能,那就暂且放在一边吧,比如现在比较火的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 = 0; i < 20; i++){stringbuilder.Append("something");}}[HttpGet]public IHttpActionResult GetSecond(){StringBuilder stringbuilder = new StringBuilder();for (int i = 0; i < 20; 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 = 0; i < 1000; i++){voidTimes.Add(getResponse(voidUrl));Thread.Sleep(10);Console.WriteLine("void Test " + i);}Console.WriteLine("Finished Void Test");for (int i = 0; i < 1000; i++){httpTimes.Add(getResponse(httpUrl));Thread.Sleep(10);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 = 0; i < 200000; i++){stringbuilder.Append("something");}

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

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

WebHost

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

        [HttpGet][Route("test/void")]public void GetFirst(){StringBuilder stringbuilder = new StringBuilder();for (int i = 0; i < 20; i++){stringbuilder.Append("something");}}[HttpGet][Route("test/IHttpActionResult")]public IHttpActionResult GetSecond(){StringBuilder stringbuilder = new StringBuilder();for (int i = 0; i < 20; 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

 

转载于:https://www.cnblogs.com/CreateMyself/p/5838467.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

射击大战H5

欢迎来到程序小院 射击大战 玩法&#xff1a;移动鼠标控制方向&#xff0c;敌人从四周来袭&#xff0c;看到敌人点击鼠标左键射击&#xff0c;不要让敌人接近你&#xff0c; 碰到敌人生命值减少&#xff0c;生命值为空游戏结束&#xff0c;快去射击吧^^。开始游戏https://www.…

File类的使用

常用构造器&#xff1a; package File;import org.junit.Test;import java.io.File;public class FileTest {Testpublic void test1(){ // 如何创建File类的实例&#xff1a;构造器一&#xff1a; // 相对于当前module // (相对路径)相较于某个路径下File…

php正规则表达式学习笔记(几个常用函数的区别)

preg_mache()函数和 preg_mache_all()函数的区别&#xff1a; preg_mache()只会匹配规则中的字符一次&#xff0c; preg_mache_all()会匹配符合条件的所有字符&#xff01; 例子对比&#xff1a; 正则表达式函数之preg_replace()与preg_filter()的区别&#xff1a; preg_replac…

IO流的体系及FileReader、FileWriter

package IOStream;import org.junit.Test;import java.io.File; import java.io.FileReader; import java.io.IOException;public class FileReadWriter {//Testpublic void testFileReader() { // fr需要提前声明FileReader fr null; // 1.实例化File类的对象…

使用R进行相关性分析

基于R进行相关性分析 一、相关性矩阵计算&#xff1a; [1] 加载数据&#xff1a; >data read.csv("231-6057_2016-04-05-ZX_WD_2.csv",headerFALSE) 说明&#xff1a;csv格式的数据&#xff0c;headerFALSE 表示没有标题&#xff0c;即数据从第一行开始。 [2] …

FileInputStream与FileOutputStream

FileReader与FileWriter 只能用于文本文件&#xff0c;如.txt,.java,.c,.c等 对于图片&#xff0c;视频等字节流文件需要用字节流即&#xff1a;FileInputStream与FileOutputStream package IOStream;import org.junit.Test;import java.io.File; import java.io.FileInputS…

缓冲流的介绍

package BufferStream; /* 缓冲流的使用*/ import org.junit.Test;import java.io.*;public class BufferTest {/*实现非文本文件的复制*/Testpublic void BufferedStreamTest() throws IOException {BufferedInputStream bis null;BufferedOutputStream bos null;try { // …

转换流的介绍

InputStreamReader与OutputStreamWriter 也是处理流 package TransformStream;import org.junit.Test;import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader;public class InputStreamReaderTest {Testpublic void test1() throws…

DOM事件与jQuery事件的是非纠葛

在javascript和JQuery之中&#xff0c;都有事件的处理方式&#xff0c;在我们编写程序实现某些功能的时候&#xff0c;我们会发现使用原生的DOM事件与JQuery中封装的事件都能实现同样的效果&#xff0c;那么也许我们会认为他们之间的区别不是很大&#xff0c;甚至说基本没有区别…

其他流的使用

输入输出流 数据流&#xff1a; /*数据流DataInputStream和DataOutputStream作用&#xff1a;用于基本数据类型遍历或字符串的读取和写入*/Testpublic void test1() throws IOException { // 写入操作DataOutputStream dos new DataOutputStream(new FileOutputStream(…

NDK环境配置

Android Studio 配置 &#xff08;不是SDK&#xff0c;麻烦各位看官看清楚&#xff09; 手动配置 步骤一:下载sdk 下载方式有两种 一官方下载(请***) https://developer.android.com/ndk/index.html 二在studio中下载&#xff08;如下载慢”拿梯子FQ”&#xff09; 选择NDK和…

Class类的理解

package JavaReflcet;import org.junit.Test;public class ClassTest {/*获取Class的实例的方式*/Testpublic void test1() throws ClassNotFoundException { // 方式一&#xff1a;调用运行时类的属性: .classClass clazz person.class;System.out.println(clazz);// …

面向对象概述(课堂笔记)

例如&#xff1a; //创建一个Scanner(扫描器)类型的工具实例&#xff08;对象&#xff09;&#xff0c;用于获取用户从键盘输入的数据 Scanner scannew Scanner(System.in); //创建一个Random(随机)类型的工具实例&#xff08;对象&#xff09;&#xff0c;用来生成随机数 Rand…

关于__str__的介绍

在python语言里&#xff0c;__str__一般是格式是这样的。class A: def __str__(self): return "this is in str"事实上&#xff0c;__str__是被print函数调用的&#xff0c;一般都是return一个什么东西。这个东西应该是以字符串的形式表现的。如果不是要用…