精华内容
下载资源
问答
  • webapi 异步返回

    2017-08-30 09:04:00
    两年前我遇到一个难题: ...WebAPI中使用socket如果在server端回复了再返回值? 现在终于做出一种实现了: [HttpGet] public ApiActionResult OnceBackDemo() { var result = new ApiAct...

    两年前我遇到一个难题:

    https://q.cnblogs.com/q/78177

    WebAPI中使用socket如果在server端回复了再返回值?

    现在终于做出一种实现了:

     [HttpGet]
            public ApiActionResult OnceBackDemo()
            {
                var result = new ApiActionResult()
                {
                    Success = false,
                    Result = null,
                    Message = "操作失败。"
                };
                System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false);
                mre.Reset();
                Random rm = new Random();
                Action<Stopwatch> task = (sw) =>
                {
                    sw.Start();
                    int rm_val = rm.Next(1000);
                    System.Threading.Thread.Sleep(rm_val);
                };
                var sw_out = new Stopwatch();
                task.BeginInvoke(sw_out, (ar) =>
                {
                    task.EndInvoke(ar);
                    mre.Set();
                    sw_out.Stop();
                    result.Success = true;
                    result.Message = DateTime.Now + "->操作成功,耗时:" + sw_out.ElapsedMilliseconds.ToString()+"毫秒。";
                }, null);
                if (!mre.WaitOne(1500))
                {
                    return result; 
                }
                return result;
            }
    

      

           

    转载于:https://www.cnblogs.com/datacool/p/datacool_2017_webapi.html

    展开全文
  • 还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 今天公司总部要求各个分公司把短信接口对接上,所谓的...

    还是那几句话:

    学无止境,精益求精

    十年河东,十年河西,莫欺少年穷

    学历代表你的过去,能力代表你的现在,学习代表你的将来

    废话不多说,直接进入正题:

    今天公司总部要求各个分公司把短信接口对接上,所谓的短信接口其实就是GET或者Post请求,接到这个任务感觉好Easy。

    但是真正写起来,你会发现各种各样的问题,比如请求报401错误,报400错误,报..等等各种意想不到的错误!总之,在这个过程中尝试了三个方法:

    第一个方法如下(由于第一个方法封装的比较多,在此仅仅截图),如下:

    小矩形内得POST方法,结果发现报400错误。

    紧接着我又尝试了第二种方法(这种方法比较简单,一般的POST请求都可以完成)

    第二种方法如下(2014年微信公众号开发中,好多请求我都用的这个方法):

    public static string GetPage(string posturl, string postData)
            {
                //WX_SendNews news = new WX_SendNews(); 
                //posturl: news.Posturl;
                //postData:news.PostData;
                System.IO.Stream outstream = null;
                Stream instream = null;
                StreamReader sr = null;
                HttpWebResponse response = null;
                HttpWebRequest request = null;
                Encoding encoding = Encoding.UTF8;
                byte[] data = encoding.GetBytes(postData);
                // 准备请求...  
                try
                {
                    // 设置参数  
                    request = WebRequest.Create(posturl) as HttpWebRequest;
                    CookieContainer cookieContainer = new CookieContainer();
                    request.CookieContainer = cookieContainer;
                    request.AllowAutoRedirect = true;
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = data.Length;
                    outstream = request.GetRequestStream();
                    outstream.Write(data, 0, data.Length);
                    outstream.Close();
                    //发送请求并获取相应回应数据  
                    response = request.GetResponse() as HttpWebResponse;
                    //直到request.GetResponse()程序才开始向目标网页发送Post请求  
                    instream = response.GetResponseStream();
                    sr = new StreamReader(instream, encoding);
                    //返回结果网页(html)代码  
                    string content = sr.ReadToEnd();
                    string err = string.Empty;
    
                    return content;
                }
                catch (Exception ex)
                {
                    string err = ex.Message;
                    return string.Empty;
                }
            }
    View Code

    结果这个方法报401错误。

    无奈,又在Git Hub上找了个方法,如下:

    /*
     * Created by SharpDevelop.
     * User: RedXu
     * Date: 2015-04-16
     * Time: 13:58
     * 
     */
    using System;
    using System.Net;
    using System.IO;
    using System.Text;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    
    namespace RedXuCSharpClass
    {
        /// <summary>
        /// Http操作类.
        /// </summary>
        public class HttpHelper
        {
            private const int ConnectionLimit = 100;
            //编码
            private Encoding _encoding = Encoding.Default;
            //浏览器类型
            private string[] _useragents = new string[]{
                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)",
                "Mozilla/5.0 (Windows NT 6.1; rv:36.0) Gecko/20100101 Firefox/36.0",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0"
            };
    
            private String _useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36";
            //接受类型
            private String _accept = "text/html, application/xhtml+xml, application/xml, */*";
            //超时时间
            private int _timeout = 30 * 1000;
            //类型
            private string _contenttype = "application/x-www-form-urlencoded";
            //cookies
            private String _cookies = "";
            //cookies
            private CookieCollection _cookiecollection;
            //custom heads
            private Dictionary<string, string> _headers = new Dictionary<string, string>();
    
            public HttpHelper()
            {
                _headers.Clear();
                //随机一个useragent
                _useragent = _useragents[new Random().Next(0, _useragents.Length)];
                //解决性能问题?
                ServicePointManager.DefaultConnectionLimit = ConnectionLimit;
            }
    
            public void InitCookie()
            {
                _cookies = "";
                _cookiecollection = null;
                _headers.Clear();
            }
    
            /// <summary>
            /// 设置当前编码
            /// </summary>
            /// <param name="en"></param>
            public void SetEncoding(Encoding en)
            {
                _encoding = en;
            }
    
            /// <summary>
            /// 设置UserAgent
            /// </summary>
            /// <param name="ua"></param>
            public void SetUserAgent(String ua)
            {
                _useragent = ua;
            }
    
            public void RandUserAgent()
            {
                _useragent = _useragents[new Random().Next(0, _useragents.Length)];
            }
    
            public void SetCookiesString(string c)
            {
                _cookies = c;
            }
    
            /// <summary>
            /// 设置超时时间
            /// </summary>
            /// <param name="sec"></param>
            public void SetTimeOut(int msec)
            {
                _timeout = msec;
            }
    
            public void SetContentType(String type)
            {
                _contenttype = type;
            }
    
            public void SetAccept(String accept)
            {
                _accept = accept;
            }
    
            /// <summary>
            /// 添加自定义头
            /// </summary>
            /// <param name="key"></param>
            /// <param name="ctx"></param>
            public void AddHeader(String key, String ctx)
            {
                //_headers.Add(key,ctx);
                _headers[key] = ctx;
            }
    
            /// <summary>
            /// 清空自定义头
            /// </summary>
            public void ClearHeader()
            {
                _headers.Clear();
            }
    
            /// <summary>
            /// 获取HTTP返回的内容
            /// </summary>
            /// <param name="response"></param>
            /// <returns></returns>
            private String GetStringFromResponse(HttpWebResponse response)
            {
                String html = "";
                try
                {
                    Stream stream = response.GetResponseStream();
                    StreamReader sr = new StreamReader(stream, _encoding);
                    html = sr.ReadToEnd();
    
                    sr.Close();
                    stream.Close();
                }
                catch (Exception e)
                {
                    Trace.WriteLine("GetStringFromResponse Error: " + e.Message);
                }
    
                return html;
            }
    
            /// <summary>
            /// 检测证书
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="certificate"></param>
            /// <param name="chain"></param>
            /// <param name="errors"></param>
            /// <returns></returns>
            private bool CheckCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                return true;
            }
    
            /// <summary>
            /// 发送GET请求
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public String HttpGet(String url)
            {
                return HttpGet(url, url);
            }
    
    
            /// <summary>
            /// 发送GET请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="refer"></param>
            /// <returns></returns>
            public String HttpGet(String url, String refer)
            {
                String html;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "GET";
                    request.Referer = refer;
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.UnsafeAuthenticatedConnectionSharing = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                        {
                            c.Domain = request.Host;
                        }
    
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    html = GetStringFromResponse(response);
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
    
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        string tmpcookie = response.Headers["Set-Cookie"];
                        _cookiecollection.Add(ConvertCookieString(tmpcookie));
                    }
    
                    response.Close();
                    return html;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpGet Error: " + e.Message);
                    return String.Empty;
                }
            }
    
            /// <summary>
            /// 获取MINE文件
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public Byte[] HttpGetMine(String url)
            {
                Byte[] mine = null;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "GET";
                    request.Referer = url;
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.UnsafeAuthenticatedConnectionSharing = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                            c.Domain = request.Host;
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream stream = response.GetResponseStream();
                    MemoryStream ms = new MemoryStream();
    
                    byte[] b = new byte[1024];
                    while (true)
                    {
                        int s = stream.Read(b, 0, b.Length);
                        ms.Write(b, 0, s);
                        if (s == 0 || s < b.Length)
                        {
                            break;
                        }
                    }
                    mine = ms.ToArray();
                    ms.Close();
    
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
    
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        _cookies = response.Headers["Set-Cookie"];
                    }
    
                    stream.Close();
                    stream.Dispose();
                    response.Close();
                    return mine;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpGetMine Error: " + e.Message);
                    return null;
                }
            }
    
            /// <summary>
            /// 发送POST请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public String HttpPost(String url, String data)
            {
                return HttpPost(url, data, url);
            }
    
            /// <summary>
            /// 发送POST请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="data"></param>
            /// <param name="refer"></param>
            /// <returns></returns>
            public String HttpPost(String url, String data, String refer)
            {
                String html;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.Referer = refer;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "POST";
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
    
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                        {
                            c.Domain = request.Host;
                            if (c.Domain.IndexOf(':') > 0)
                                c.Domain = c.Domain.Remove(c.Domain.IndexOf(':'));
                        }
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
                    byte[] buffer = _encoding.GetBytes(data.Trim());
                    request.ContentLength = buffer.Length;
                    request.GetRequestStream().Write(buffer, 0, buffer.Length);
                    request.GetRequestStream().Close();
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    html = GetStringFromResponse(response);
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        string tmpcookie = response.Headers["Set-Cookie"];
                        _cookiecollection.Add(ConvertCookieString(tmpcookie));
                    }
    
                    response.Close();
                    return html;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpPost Error: " + e.Message);
                    return String.Empty;
                }
            }
    
    
            public string UrlEncode(string str)
            {
                StringBuilder sb = new StringBuilder();
                byte[] byStr = _encoding.GetBytes(str);
                for (int i = 0; i < byStr.Length; i++)
                {
                    sb.Append(@"%" + Convert.ToString(byStr[i], 16));
                }
    
                return (sb.ToString());
            }
    
            /// <summary>
            /// 转换cookie字符串到CookieCollection
            /// </summary>
            /// <param name="ck"></param>
            /// <returns></returns>
            private CookieCollection ConvertCookieString(string ck)
            {
                CookieCollection cc = new CookieCollection();
                string[] cookiesarray = ck.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < cookiesarray.Length; i++)
                {
                    string[] cookiesarray_2 = cookiesarray[i].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    for (int j = 0; j < cookiesarray_2.Length; j++)
                    {
                        string[] cookiesarray_3 = cookiesarray_2[j].Trim().Split("=".ToCharArray());
                        if (cookiesarray_3.Length == 2)
                        {
                            string cname = cookiesarray_3[0].Trim();
                            string cvalue = cookiesarray_3[1].Trim();
                            if (cname.ToLower() != "domain" && cname.ToLower() != "path" && cname.ToLower() != "expires")
                            {
                                Cookie c = new Cookie(cname, cvalue);
                                cc.Add(c);
                            }
                        }
                    }
                }
    
                return cc;
            }
    
    
            public void DebugCookies()
            {
                Trace.WriteLine("**********************BEGIN COOKIES*************************");
                foreach (Cookie c in _cookiecollection)
                {
                    Trace.WriteLine(c.Name + "=" + c.Value);
                    Trace.WriteLine("Path=" + c.Path);
                    Trace.WriteLine("Domain=" + c.Domain);
                }
                Trace.WriteLine("**********************END COOKIES*************************");
            }
    
        }
    }
    View Code

    结果又是没能跳出错误的怪圈,依然是401错误。

    于是,我不得不温习下 C#  HttpClient  的相关方法

    最后,还好,在公司的项目中有这种用到  HttpClient 的方法,于是抱着尝试的心里,作了测试,结果成功了!

    本人写这篇博客也是做一个记录,方便自己以后用,也方便大家遇到 WebApi请求失败时,可以尝试上述的几种方法。

    代码如下:

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KMHC.Infrastructure
    {
        public class SmsSendHelper
        {
            public string _appKey = "";
            public string _category = "";
            public string _templateNo = "";
            public string _templateid = "";
            public SmsSendHelper() { }
            public async Task<SmsSendResult> Send(string phone, string sendContent)
            {
                var Model = BuildData(phone, sendContent);
                SmsSendResult Result = new SmsSendResult();
                var hh = new HttpClient() { BaseAddress = new Uri(SmsUri.SmsSendUri), Timeout = TimeSpan.FromMinutes(30) };
                //Model 需要序列化的对象 
                var res = await hh.PostAsJsonAsync("", Model);
                if (res.StatusCode == HttpStatusCode.OK)
                {
                    var response = res.Content.ReadAsAsync<SmsSendResult>().Result;
                    return response;
                }
                return null;
            }
    
            /// <summary>
            /// 构建请求实体
            /// </summary>
            /// <param name="_phone"></param>
            /// <param name="_sendContent"></param>
            /// <returns></returns>
            private object BuildData(string _phone, string _sendContent)
            {
                var para = new
                {
                    appKey = _appKey,
                    category = _category,
                    templateNo = _templateNo,
                    templateid = _templateid,
                    phone = _phone,
                    sendContent = _sendContent
                };
                return para;
            }
        }
    }
    View Code
            [Route("test"), HttpGet, AllowAnonymous]
            public async Task<IHttpActionResult> test()
            {
                SmsSendHelper Func = new SmsSendHelper();
                var data =await Func.Send("181XXXX0152","你好!短信测试。");
                return Ok(data);
            }
    View Code

    需要引用如下命名空间:

     

    总之,很简单,也很好用。

     @陈卧龙的博客

    展开全文
  • 获取webapi异步回调函数参数

    千次阅读 2017-12-07 17:23:28
    异步回调不用说了,相信用过的人都能感觉到时多么恶心,如果像支付宝、微信等异步回调还好一点,写的比较大众化,而且还有例子可以看,如果碰上比较二的合作方就完蛋了,API写的是一塌糊涂,还没有调用案例,最近...

    异步回调不用说了,相信用过的人都能感觉到时多么恶心,如果像支付宝、微信等异步回调还好一点,写的比较大众化,而且还有例子可以看,如果碰上比较二的合作方就完蛋了,API写的是一塌糊涂,还没有调用案例,最近遇到一个公司用java给我写api,回调函数的参数用response.header和body传过来,我曹,然后跟我说参数是在请求头和请求体里面。因为什么都没有,就说了这么一句,当时就懵逼了,因为我还真没听过。net里面请求体这么一说,不过好在我在request.Headers可以获取到他们所说的请求头。。,然后各种琢磨,还真把他们的请求体搞出来了,原来他们说的请求体是http请求,在fidder调用的话是在body里面出现的,所以他们就叫他请求体,找到原因就好弄了,下面就是获取请求体的代码:

      string key = Request.Headers["key"].ToString();  这就是获取请求头

    下面开始获取请求体,所有的请求体都在我们的inputstream里面

     Stream reqStream = Request.InputStream;


    byte[] buffer = new byte[(int)reqStream.Length];

     int s = reqStream.Read(buffer, 0, (int)reqStream.Length);

    到这为止其实我们已经获取到了请求体,下面就是解析请求体里面的字符串

    string req = System.Text.Encoding.Default.GetString(buffer);

      req = Server.UrlDecode(req);

    到这req就是我们获取到的请求体的字符串了,如果是json就把他转换成json在解析,下面就是解析json格式

     JObject jo = (JObject)JsonConvert.DeserializeObject(req);

     string useruuid = jo["useruuid"].ToString();//用户id


    最后处理完成之后给对方返回字符串success表名我们成功收到并且处理了请求

     Response.Write("SUCCESS");

    展开全文
  • 很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的...

    很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的异步性能测试(有关异步和同步的问题,请参考客《AIO与BIO接口性能对比》),于是我今天写了一个C#的测试程序。

    首先,建一个 ASP.NET MVC WebAPI项目,在默认的控制器 values里面,增加两个方法:

    复制代码
     // GET api/values?sleepTime=10
            [HttpGet]
            public async Task<string> ExecuteAIO(int sleepTime)
            {
                await Task.Delay(sleepTime);
                return  "Hello world,"+ sleepTime;
            }
    
            [HttpGet]
            // GET api/values?sleepTime2=10
            public string ExecuteBIO(int sleepTime2)
            {
                System.Threading.Thread.Sleep(sleepTime2);
                return "Hello world," + sleepTime2;
            }
    复制代码

    然后,建立一个控制台程序,来测试这个web API:

      View Code

    其实主要是下面几行代码:

    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri("http://localhost:62219/");
    var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;

    注意,你可能需要使用Nuget添加下面这个包:

    Microsoft.AspNet.WebApi.Client

    最后,运行这个测试,结果如下:

    复制代码
    按任意键开始测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}
    请输入线程数:1000
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
    Result:"Hello world,10"
    1000次 BIO(同步)测试(睡眠10 毫秒):
    耗时(秒):1.2860545,QPS:    777.57
    1000次 AIO(异步)测试(睡眠10 毫秒):
    耗时(秒):0.4895946,QPS:   2042.51
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
    Result:"Hello world,100"
    1000次 BIO(同步)测试(睡眠100 毫秒):
    耗时(秒):8.2769307,QPS:    120.82
    1000次 AIO(异步)测试(睡眠100 毫秒):
    耗时(秒):0.5435111,QPS:   1839.89
    复制代码

    本来想尝试测试10000个线程,但报错了。

     

    上面的测试结果,QPS并不高,但由于使用的是IISExpress,不同的Web服务器软件性能不相同,所以还得对比下进程内QPS结果,于是新建一个控制台程序,代码如下:

      View Code

    注意,关键代码只有下面两个方法:

    复制代码
     public static async Task<string> ExecuteAIO(int sleepTime)
            {
                await Task.Delay(sleepTime);
                return "Hello world," + sleepTime;
            }
    
            public static string ExecuteBIO(int sleepTime2)
            {
                System.Threading.Thread.Sleep(sleepTime2);
                //不能在非异步方法里面使用 Task.Delay,否则可能死锁
                //Task.Delay(sleepTime2).Wait();
                return "Hello world," + sleepTime2;
            }
    复制代码

    这两个方法跟WebAPI的测试方法代码是一样的,但是调用代码稍微不同:

    同步调用:

    复制代码
     Task[] taskArr = new Task[TaskNumber];
                for (int i = 0; i < TaskNumber; i++)
                {
                    Task task = Task.Run<string>(()=> ExecuteBIO(SleepTime));
                    taskArr[i] = task;
    
                }
                Task.WaitAll(taskArr);
    复制代码

    异步调用:

    复制代码
     for (int i = 0; i < TaskNumber; i++)
                {
                    Task task = ExecuteAIO(SleepTime);
                    taskArr[i] = task;
                }
                Task.WaitAll(taskArr);
    复制代码

    可见,这里测试的时候,同步和异步调用,客户端代码都是使用的多线程,主要的区别就是异步方法使用了 async/await 语句。

    下面是非Web的进程内异步多线程和同步多线程的结果:

    复制代码
    请输入线程数:1000
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
    Result:Hello world,10
    1000次 BIO(同步)测试(睡眠10 毫秒):
    耗时(秒):1.3031966,QPS:    767.34
    1000次 AIO(异步)测试(睡眠10 毫秒):
    耗时(秒):0.026441,QPS:  37820.05
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
    Result:Hello world,100
    1000次 BIO(同步)测试(睡眠100 毫秒):
    耗时(秒):9.8502858,QPS:    101.52
    1000次 AIO(异步)测试(睡眠100 毫秒):
    耗时(秒):0.1149469,QPS:   8699.67
    
    请输入线程数:10000
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
    Result:Hello world,10
    10000次 BIO(同步)测试(睡眠10 毫秒):
    耗时(秒):7.7966125,QPS:   1282.61
    10000次 AIO(异步)测试(睡眠10 毫秒):
    耗时(秒):0.083922,QPS: 119158.27
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
    Result:Hello world,100
    10000次 BIO(同步)测试(睡眠100 毫秒):
    耗时(秒):34.3646036,QPS:    291.00
    10000次 AIO(异步)测试(睡眠100 毫秒):
    耗时(秒):0.1721833,QPS:  58077.64
    复制代码

    结果表示,.NET程序开启10000个任务(不是10000个原生线程,需要考虑线程池线程),异步方法的QPS超过了10万,而同步方法只有1000多点,性能差距还是很大的。

    注:以上测试结果的测试环境是 

    Intel i7-4790K CPU,4核8线程,内存 16GB,Win10 企业版

     

    总结:

    不论是普通程序还是Web程序,使用异步多线程,可以极大的提高系统的吞吐量。

     

    后记:

    感谢网友“双鱼座” 的提示,我用信号量和都用线程Sleep的方式,对同步和异步方法进行了测试,结果如他所说,TPL异步方式,开销很大,下面是测试数据:

    复制代码
    使用 semaphoreSlim 的情况:
    
    请输入线程数:1000
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
    Result:Hello world,10
    1000次 BIO(同步)测试(睡眠10 毫秒):
    耗时(秒):1.2486964,QPS:    800.84
    1000次 AIO(异步)测试(睡眠10 毫秒):
    耗时(秒):10.5259443,QPS:     95.00
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
    Result:Hello world,100
    1000次 BIO(同步)测试(睡眠100 毫秒):
    耗时(秒):12.2754003,QPS:     81.46
    1000次 AIO(异步)测试(睡眠100 毫秒):
    耗时(秒):100.5308431,QPS:      9.95
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:1000
    Result:Hello world,1000
    1000次 BIO(同步)测试(睡眠1000 毫秒):
    耗时(秒):54.0055828,QPS:     18.52
    1000次 AIO(异步)测试(睡眠1000 毫秒):
    耗时(秒):1000.4749124,QPS:      1.00
    复制代码

    使用线程 Sleep的代码改造:

    复制代码
      public static async Task<string> ExecuteAIO(int sleepTime)
            {
                //await Task.Delay(sleepTime);
                //return "Hello world," + sleepTime;
                //await Task.Delay(sleepTime);
                //semaphoreSlim.Wait(sleepTime);
                System.Threading.Thread.Sleep(sleepTime);
                return await Task.FromResult("Hello world," + sleepTime);
            }
    
            public static string ExecuteBIO(int sleepTime2)
            {
                System.Threading.Thread.Sleep(sleepTime2);
                //semaphoreSlim.Wait(sleepTime2);
                //不能在非异步方法里面使用 Task.Delay,否则可能死锁
                //Task.Delay(sleepTime2).Wait();
                return "Hello world," + sleepTime2;
            }
    复制代码

    运行结果如下:

    复制代码
    请输入线程数:1000
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
    Result:Hello world,10
    1000次 BIO(同步)测试(睡眠10 毫秒):
    耗时(秒):1.3099217,QPS:    763.40
    1000次 AIO(异步)测试(睡眠10 毫秒):
    耗时(秒):10.9869045,QPS:     91.02
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
    Result:Hello world,100
    1000次 BIO(同步)测试(睡眠100 毫秒):
    耗时(秒):8.5861461,QPS:    116.47
    1000次 AIO(异步)测试(睡眠100 毫秒):
    耗时(秒):100.9829406,QPS:      9.90
    请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:1000
    Result:Hello world,1000
    1000次 BIO(同步)测试(睡眠1000 毫秒):
    耗时(秒):27.0158904,QPS:     37.02
    1000次 AIO(异步)测试(睡眠1000 毫秒):
    复制代码

    在每次睡眠1秒的异步方法测试中,很久都没有出来结果,不用考虑,QPS肯定低于一秒了。

    经验教训:

    在异步方法中,不要使用 Thread.Sleep;在同步方法中,不要使用Task.Delay ,否则可能出现线程死锁,结果难出来。




        本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/p/7562705.html,如需转载请自行联系原作者


    展开全文
  • ASP.NET WEBAPI异步视频流实现

    千次阅读 2015-06-26 17:49:53
    要执行异步流任务,可以使用PushStreamContent。它允许服务器逐步推到接收客户端的数据包。本示例中,从服务器的硬盘上的文件读取视频流并刷新到客户端 (使用PushStreamContent) 65536 字节的数据包。流媒体视频播放...
  • 使用异步调用一个树结构 ``` public async Task<List<SelectDto>> SelectDeps(int? id) { var results = new List(); // var deps = db.Department.Where(o=>o.IsDel!=true).Where(o => o.Pid == id || ...
  • 异步WebApi结合案例

    2016-11-11 16:30:53
    异步WebApi结合案例
  • 最近学习COREapi,给大家来个API上传资源1,1 c# ajax调用webapi上传图片、传值 demo,2 C#web上传下载文件源码.rar ,3c#Web异步上传图片和海量图片上传案例.zip
  • 实施Slack的大多数Web API 积极维护该项目 提供按方法进行内存中的速率限制,因此您不必担心单个进程会造成压倒性的负担 公开高度可配置的钩子,以允许自定义速率限制,方法筛选和调试,以可扩展的方式进行 重大...
  • EF+MVC+增删改查+webapi+异步上传文件+类库大全 只能选择5分 解决了 多种文体 。网上的其他的要么分数太高 要么下载来没有用
  • 前面我们讲过利用AngularJs上传到WebAPi中进行处理,同时我们在MVC系列中讲过文件上传,本文结合MVC+WebAPi来进行文件的同步或者异步上传,顺便回顾下css和js,MVC作为客户端,而WebAPi利用不依赖于IIS的selfhost...
  • Web API /ASP.NET MVC中的异步编程
  • .net mvc webapi使用异步请求处理并发

    千次阅读 2019-09-30 00:31:52
    model.cs中 #region 根据学年获取老师在的班级 public class TeacherClassForYearPara { public string YearCode { set; get; } public string UserCode { set; get; } ... publi...
  • ASP.NET MVC WebAPI REST C# 使用ASP.NET MVC创建WebAPI REST的示例 使用C#语言; 使用Visual Studio 2015; 使用MySQL数据库; 在MySql上使用StoreProcedures; 在所有方法和动词中使用异步任务调用。 使用...
  • 使用JQuery,FormData和ASP.NET Web Api上传异步文件 源代码
  • 本讲比较实际,在WEB端有一个Index和Create方法,用来从web api显示实体列表数据和向api插入实体对象,这就是以往的网站,只不过是把数据持久化过程放到了web pai上面,它的优势不用说,就是跨平台,跨语言,这其实...
  • 流利的Spotify API 具有流畅语法的.NET 5异步客户端。 安装与配置 使用以下命令安装客户端NuGet软件包: Install-Package FluentSpotifyApi 安装完成后,您可以将客户端与其他服务一起注册到组合根目录中: ...
  • web api接口同步和异步的问题

    千次阅读 2016-09-29 21:33:00
    一般来说,如果一个api 接口带上Task和 async 一般就算得上是异步api接口了。 如果我想使用异步api接口,一般的动机是我在我的方法里面可能使用Task.Run 进行异步的去处理一个耗时的操作。 Q1.如果一个api接口很...
  • Web API控制器动作可以返回下列的任何值: 1, void 2, HttpResponseMessage 3, IHttpActionResult 4, Some other type取决于返回的以上哪一种,Web API使用不同的机制来创建HTTP响应。 Return type
  • Flask-WebAPI 使用Flask通过Web API与机器学习模型进行交互。 目录 介绍 Web API允许其他程序通过Internet操纵信息或功能。可以将机器学习模型部署,托管在服务器上,并通过Web API进行交互。 Flask是Python的API,...
  • .Net Core WebAPI 基于...并行任务(Task)以及基于Task的异步编程(asynchronously)在.NET Framework早已使用多年,而在微软新推出的.NET Core 平台下也有相同功能的实现,本文将通过.NET Core WebAPI,介绍使用Tas...
  • :1st_place_medal: 使用ASP.NET Core WebAPI的专业REST API设计 该项目是使用ASP.NET Core构建RESTful Web API的轻量级和可扩展基础结构的示例。 此示例包含许多技巧和技术,这些技巧和技术是我多年在ASP.NET Core...
  • 用于在 ASP.NET Web API 中读取和设置 ETag 标头的异步模式。 目标 单个文件,如 PetaPoco / Massive 仅 ETag,至少一开始 指定方式 ETag查找功能 模型获取函数 具有当前 ETag 的模型的属性 注意检查请求头和设置...
  •  ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台。 一、定义Web API 二、Web API入门 “新建”->“项目”,已安装下的 “模板” ->Visual C# -> Web -> ASP.NET
  • .NET 4.0 webapi jsonp方案。
  • 异步的实质就是线程的切换(遇到await),同一请求下,异步和同步的执行时间是一样的,但有人说异步可以提高XXX性能,但具体是什么性能呢?又说不上来,其实就只提高并发量,并不能提升你应用程序处理的速度 使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 141,383
精华内容 56,553
关键字:

webapi怎么异步