C#多线程TPL模式下使用HttpClient

一、引言

我们有时侯需要在程序里面调用Http接口、请求http资源、编写http爬虫等的时候都需要在程序里面进行Http请求。很多人习惯的WebClient、HttpWebRequest在TPL下有很多用起来不方便的地方,TPL下推荐使用HttpClient(using System.Net.Http),而且在.NET Core下已经不在支持WebClient等。

1、发送Get请求

HttpClient发出Get请求获取文本响应,如下面的代码:

// 实例化HttpClient对象
HttpClient hc = new HttpClient();
// 发送Get请求获取
string strContent =await hc.GetStringAsync("http://www.baidu.com");

2、发送Post请求

HttpClient发送Post请求使用Task<HttpResponseMessage> PostAsync(string requestUri,HttpContent content)方法,方法的第一个参数是请求的地址,第二个参数用来设置请求内容。HttpContent是抽象类,主要有下面的几个子类:

  • FormUrlEncodedContent:表示用来发送表单格式的请求。
  • StringContent:表示用来发送字符串请求。
  • MultipartFormDataContent:Multipart发送表单请求,一般带上传文件信息。
  • StreamContent:发送流内容。

二、实例

下面我们看一个使用HttpClient发送Post请求的实例。我们创建一个MVC项目,控制器里面有三个Post请求的方法,分别模拟三种不同内容的Http请求,代码如下:

using System.Web;
using System.Web.Mvc;

namespace HttpClientMVCTestDemo.Controllers
{
    public class LoginRequest
    {
        public string userName { get; set; }
        public string password { get; set; }
    }

    public class HttpClientTestController : Controller
    {
        // GET: HttpClientTest
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 发送表单请求
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost]
        public string Login(string userName, string password)
        {

            if (userName == "admin" && password == "123")
            {
                return "ok";
            }
            else
            {
                return "error";
            }
        }

        /// <summary>
        /// 发送Json格式的请求
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public string Login2(LoginRequest data)
        {
            string userName = data.userName;
            string password = data.password;
            if (userName == "admin" && password == "123")
            {
                return "ok";
            }
            else
            {
                return "error";
            }
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public string Upload(HttpPostedFileBase file)
        {
            string userName = Request.Headers["UserName"];
            string password = Request.Headers["Password"];
            if (userName == "admin" && password == "123")
            {
                // 保存文件
                file.SaveAs(Server.MapPath("~/" + file.FileName));
                return "ok";
            }
            else
            {
                return "error";
            }
        }
    }
}

然后创建一个Winform程序,用来发送Http请求。界面上有三个按钮,分别发送三种不同内容的Http请求。

1、发送表单内容的请求

我们看下面发送表单请求的代码:

/// <summary>
/// 模拟发送表单内容的Http请求
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btnForm_Click(object sender, EventArgs e)
{
    // 实例化对象
    HttpClient client = new HttpClient();
    Dictionary<string, string> dic = new Dictionary<string, string>();
    dic["userName"] = "admin";
    dic["password"] = "123";
    // 参数
    FormUrlEncodedContent content = new FormUrlEncodedContent(dic);
    // 发送post请求
    HttpResponseMessage responseMsg = await client.PostAsync("http://localhost:55179/HttpClientTest/login", content);
    // 返回报文体
    // responseMsg.Content
    // 返回响应头
    // responseMsg.Headers
    // 返回响应码
    // responseMsg.StatusCode
    // 获取返回值 这里确定返回的是字符串,调用string
    string msg =await responseMsg.Content.ReadAsStringAsync();
    MessageBox.Show($"响应码:{responseMsg.StatusCode.ToString()}");
    MessageBox.Show($"返回内容:{msg}");
}

程序运行结果:

点击“确定”,查看返回内容:

2、发送json格式内容的请求

下面是发送json内容请求的代码:

/// <summary>
/// 发送json
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btnJson_Click(object sender, EventArgs e)
{
    // json格式的字符串
    string jsonData = "{userName:'admin',password:'123'}";
    // 实例化对象
    HttpClient client = new HttpClient();
    StringContent content = new StringContent(jsonData);
    // 设置contentType,必须要设置 设置为json格式,MVC会自动转换成Model类型
    content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
    // 发送post请求
    HttpResponseMessage responseMsg = await client.PostAsync("http://localhost:55179/HttpClientTest/login2", content);
    // 获取返回值
    string msg = await responseMsg.Content.ReadAsStringAsync();
    MessageBox.Show($"响应码:{responseMsg.StatusCode.ToString()}");
    MessageBox.Show($"返回内容:{msg}");
}

3、上传文件

看一下上传文件的代码:

/// <summary>
/// 上传文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btnUpload_Click(object sender, EventArgs e)
{
    // 实例化对象
    HttpClient client = new HttpClient();
    MultipartFormDataContent content = new MultipartFormDataContent();
    content.Headers.Add("UserName", "admin");
    content.Headers.Add("Password", "123");
    using (Stream stream = File.OpenRead(@"F:\数据库.txt"))
    {
        content.Add(new StreamContent(stream), "file", "test.txt");
        HttpResponseMessage responseMsg = await client.PostAsync("http://localhost:55179/HttpClientTest/Upload", content);
        // 返回值
        string msg = await responseMsg.Content.ReadAsStringAsync();
        MessageBox.Show($"响应码:{responseMsg.StatusCode.ToString()}");
        MessageBox.Show($"返回内容:{msg}");
    }
}

点击上传文件按钮以后,就能在服务器端看到我们上传的文件了。

到此这篇关于C#多线程TPL模式下使用HttpClient的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#多线程TPL常见操作误区与异常处理

    一.一定要async到底 一定要让async的传染性(调用异步方法要用await,用了await的方法就要声明为async,调用我这个async方法的地方必须要await.....)不要轻易直接调用Task的Wait.WaitAll等方法.等待一个用await,而不是task.Wait():等待多个用await Task.WhenAll(),而不是Task.WaitAll(). 二.用了异步性能不一定高 程序里面使用了异步不一定说性能就一定高,下面的异步方法就没有意义: public async

  • C#多线程TPL模式高级用法探秘

    一.引言 我们先来看下面的一个小示例:一个Winfrom程序,界面上有一个按钮,有两个异步方法,点击按钮调用两个异步方法,弹出执行顺序,代码如下: using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace TPLDemoSln { public partial class Form1 : Form { public Form1() { Init

  • ASP.NET MVC使用异步TPL模式

    1.MVC中如何使用异步 我们新建一个MVC的项目,我们在Home控制器的Index方法里面读取一个文件的内容,然后返回给用户,我们看下面的代码: /// <summary> /// 异步方法 /// </summary> /// <returns></returns> public Task<ActionResult> Index() { return Task.Run<ActionResult>(() => { using

  • C#多线程TPL模式下使用HttpClient

    一.引言 我们有时侯需要在程序里面调用Http接口.请求http资源.编写http爬虫等的时候都需要在程序里面进行Http请求.很多人习惯的WebClient.HttpWebRequest在TPL下有很多用起来不方便的地方,TPL下推荐使用HttpClient(using System.Net.Http),而且在.NET Core下已经不在支持WebClient等. 1.发送Get请求 HttpClient发出Get请求获取文本响应,如下面的代码: // 实例化HttpClient对象 Http

  • 详谈ThreadLocal-单例模式下高并发线程安全

    目录 ThreadLocal-单例模式下高并发线程安全 为了解决线程安全的问题,我们有3个思路: 多线程中的ThreadLocal 1.ThreadLocal概述 2. ThreadLocal简单实用 3.ThreadLocal的内部原理 3.1 get方法 3.2 set方法 3.3 remove方法 3.4 initialValue方法 4. 总结 5. ThreadLocalMap引发的内存泄漏 ThreadLocal-单例模式下高并发线程安全 在多例的情况下,每个对象在堆中声明内存空间,

  • Angularjs在360兼容模式下取数据缓存问题的解决办法

    测试提了一个bug,在360浏览器兼容模式下,删除页面数据需要手动刷新浏览器才能看到最新的数据.首先要复现当时的问题,很容易就复现了,但是发现在360浏览器兼容模式下无法打开开发者工具.好在经过反复重装之后,终于打开了开发者工具,经过跟踪发现,第一次删除数据时可以正常刷新,第二次或以后的删除将无法刷新,跟踪代码,发现通过异步请求的数据正常的返回并且绑定了.点击搜索按钮,也无法实现刷新,但是点击分页,发现可以翻页.初步推断是浏览器缓存了异步请求数据,跟踪比较返回的数据发现,推断是正确的.于是从网上

  • Vue单页式应用(Hash模式下)实现微信分享的实例

    本文介绍了Vue单页式应用(Hash模式下)实现微信分享的实例,分享给大家,具体如下: 前端微信分享的基本步骤: 一.绑定域名: 先登录微信公众平台进入"公众号设置"的"功能设置"里填写"JS接口安全域名".这个不多说,微信开发的都应该清楚. 二.引入js文件: 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js. 请注意,如果你的页面启用了ht

  • MVVM模式下WPF动态绑定展示图片

    MVVM模式下WPF动态展示图片,界面选择图标,复制到项目中固定目录下面,保存到数据库的是相对路径,再次读取的时候是根据数据库的相对路径去获取项目中绝对路径的图片展示. 首先在ViewModel中 //属性定义 BitmapImage _ImageSource; /// <summary> /// 显示的图标 /// </summary> public BitmapImage ImageSource { get { return _ImageSource; } set { _Ima

  • JavaScript严格模式下关于this的几种指向详解

    前言 相信不少人在学习或者使用Javascript的时候,都曾经被 JavaScript 中的 this 弄晕了,那么本文就来整理总结一下在严格模式下 this 的几种指向. 一.全局作用域中的this 在严格模式下,在全局作用域中,this指向window对象 "use strict"; console.log("严格模式"); console.log("在全局作用域中的this"); console.log("this.docume

  • php cli模式下获取参数的方法

    PHP在cli模式下接收参数有两种方法 1.使用argv数组 2.使用getopt方法 1.使用argv数组 例如:需要执行一个php,并传递三个参数(type=news, is_hot=1, limit=5) 创建test.php <?php print_r($argv); ?> 在命令行执行 php test.php news 1 5 输出: Array ( [0] => test.php [1] => news [2] => 1 [3] => 5 ) 可以看到ar

  • ThinkPHP在Cli模式下使用模板引擎的方法

    本文实例讲述了ThinkPHP在Cli模式下使用模板引擎的方法.分享给大家供大家参考.具体如下: 关于Cli模式与模版引擎,2.1中的手册是这样说明的: Cli模式默认不使用任何模板引擎(可以自己在操作方法里面调用): 但是怎么调用,手册中没有提到.于是自己动手丰衣足食. 在介绍怎么调用之前,简单的说说什么情况可能需要用到模块引擎: 1. 利用dompdf在计划任务自动生成PDF或HTML报告 2. 计划任务发送HTML类型的邮件 3. 后台自动生成静态页面 4. 其他关于模板的后台操作 <?p

随机推荐