很多情况下一般会使用同步方式发出请求,直到响应后再做后续的逻辑处理等,但有时候后续的逻辑处理不依赖于请求的结果或者是可以挂起等到响应后再处理,又或者是为了解决UI“假死”的现象,这时可以使用异步请求

使用WebRequest实例中的BeginGetResponse方法异步获取响应结果,其中参数callback是委托类型,state是自定义的对象,state用于保存一些信息,在callback对应的方法中可能需要用到这些信息。

下面用一个例子说明,假设需要请求url,该url对应是一张图片,异步获取后展示到PictureBox中(该例子基于winform的一个窗体中)

winform中定义了存放数据的变量

List<byte> lstBuffer = new List<byte>();
byte[] buffers = new byte[];

在具体需要请求服务器的地方创建WebRequest实例,并调用BeginGetResponse方法

string url = "http://localhost/1.jpg";
var request = WebRequest.Create(url);
request.BeginGetResponse(RespCallBack, request);
RespCallBack方法如下,此处ar.AsyncState也就是上面调用BeginGetResponse方法中参数state对应的信息,也就是request
private void RespCallBack(IAsyncResult ar)
{
var request = ar.AsyncState as WebRequest;
var response = request?.EndGetResponse(ar);
Stream responseStream = response?.GetResponseStream();
responseStream?.BeginRead(buffers, , , ReadCallBack, responseStream);
}

由于是异步,此处读数据也是异步读取,ReadCallBack如下:

private void ReadCallBack(IAsyncResult ar)
{
using (var responseStream = ar.AsyncState as Stream)
{
if (responseStream == null) return;
var read = responseStream.EndRead(ar);
if (read > )
{
lstBuffer.AddRange(buffers);
responseStream.BeginRead(buffers, , , ReadCallBack, responseStream);
}
else
{
lstBuffer.AddRange(buffers);
Stream s = new MemoryStream(lstBuffer.ToArray());
pictureBox1.Image = Image.FromStream(s);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
responseStream.Dispose();
}
}
}

每次读一定的字节,填充到指定的容器中(lstBuffer),当数据还没有读取完毕就一直调用responseStream.BeginRead(buffers, 0, 8, ReadCallBack, responseStream);

当读取完毕后,将读取的数据(lstBuffer)转换成图片,赋值给pictureBox。

如果是使用WebClient的方式代码量就少很多,调用DownloadDataAsync方法发起异步请求,注册事件DownloadDataCompleted,当异步请求完成的时候会触发 Wc_DownloadDataCompleted事件,Wc_DownloadDataCompleted事件中DownloadDataCompletedEventArgs类型的参数e包含一些信息,其中e.Result就是请求响应的结果(byte[]类型)

var wc = new WebClient();
wc.DownloadDataAsync(new Uri("http://localhost/1.jpg"));
wc.DownloadDataCompleted += Wc_DownloadDataCompleted;
private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
using (MemoryStream ms = new MemoryStream(e.Result))
{
if (pictureBox1 != null) pictureBox1.Image = Image.FromStream(ms);
}
}

.Net WebRequest异步请求与WebClient异步请求的更多相关文章

  1. 普通B/S架构模式同步请求与AJAX异步请求区别(个人理解)

    在上次面试的时候有被问到过AJAX同步与异步之间的概念问题,之前没有涉及到异步与同步的知识,所以特意脑补了一下,不是很全面... 同步请求流程:提交请求(POST/GET表单相似的提交操作)---服务 ...

  2. iOS 网络与多线程--5.异步Post方式的网络请求(非阻塞)

    通过Post请求方式,异步获取网络数据,异步请求不会阻塞主线程,而会建立一个新的线程来操作. 代码如下 ViewController.h文件 #import <UIKit/UIKit.h> ...

  3. iOS 网络与多线程--3.异步Get方式的网络请求(非阻塞)

    通过Get请求方式,异步获取网络数据,异步请求不会阻塞主线程(用户界面不会卡死),而会建立一个新的线程. 代码如下 ViewController.h文件 // // ViewController.h ...

  4. Ajax异步请求XMLHttpRequest对象Get请求

    $(function () { $("#btnGetDate").click(function () { var xhr; //第一步:创建异步请求的核心的对象: if (XMLH ...

  5. 第三节:总结.Net下后端的几种请求方式(WebClient、WebRequest、HttpClient)

    一. 前言 前端调用有Form表单提交,ajax提交,ajax一般是用Jquery的简化写法,在这里不再过多介绍: 后端调用大约有这些:WebCient.WebRequest.Httpclient.W ...

  6. 设计一个方法injectBeforeAsyncSend,能够实现如下功能:在发起异步请求之前打印出请求的类型、URL、method、body、timestamp 等信息。

    异步请求逻辑注入 工作中我们需要对异步请求的请求信息打印日志,但是又不能耦合在业务代码中打印.请设计一个方法injectBeforeAsyncSend,能够实现如下功能:在发起异步请求之前打印出请求的 ...

  7. js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快、简单 post:安全,量大,不缓存)(服务器同步和异步区别:同步:等待服务器响应当中浏览器不能做别的事情)(ajax和jquery一起用的)

    js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快.简单 post:安全,量大,不缓存)( ...

  8. javascript 异步请求封装成同步请求

    此方法是异步请求封装成同步请求,加上token验证,环境试用微信小程序,可以修改文件中的ajax,进行封装自己的,比如用axios等 成功码采用标准的 200 到 300 和304 ,需要可以自行修改 ...

  9. java判断请求是否ajax异步请求

    java判断请求是否ajax异步请求   解决方法: if (request.getHeader("x-requested-with") != null && re ...

随机推荐

  1. 简述serializable和transient关键字作用

    transient的作用及使用方法,官方解释为: Variables may be marked transient to indicate that they are not part of the ...

  2. JavaScript对象Object

    <script> var obj = new Object(); var obj2 = {}; obj2.firstName = "wang"; obj2.lastNa ...

  3. Python多版本管理器-pyenv 介绍及部署记录

    一. pyenv简单介绍 在日常运维中, 经常遇到这样的情况: 系统自带的Python是2.x,而业务部署需要Python 3.x 环境, 此时需要在系统中安装多个Python版本,但又不能影响系统自 ...

  4. Java 8 新特性-菜鸟教程 (1) -Java 8 Lambda 表达式

    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). 使用 Lambda 表达式可以使代码变的更加 ...

  5. Spring 通过Java代码装配bean

    1. 背景 书接上文Spring自动化装配bean 尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化扫描配置是更为推荐的方式,但在有些情况下自动化扫描的方案行不通,如想要将第三方库中的组 ...

  6. PowerBuilder编程新思维3:适配(三层架构与GraphQL)

    PowerBuilder编程新思维3:适配(三层架构与GraphQL) PB在富客户端时代,是一线开发工具.随着网络发展,主流架构演进到三层架构的时代,PB拿不出有力的三层架构,已经明显力不从心,市场 ...

  7. [转]RSReportServer 配置文件

    本文转自:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2005/ms157273(v=sql.90) 更新日期: ...

  8. pdf.js 使用汇总

    https://www.cnblogs.com/iPing9/p/7154753.htmlhttp://blog.csdn.net/m0_38021128/article/details/708684 ...

  9. Core Foundation 官方文档翻译

      Core Foundation框架中常用的隐含类型: 使用这些隐含类型时需要自己初始化,自己去释放内存.所以需要记住,在初始化的同时在相应位置释放.以防出现内存问题.   1.CFStringRe ...

  10. vue 教程

    1.安装 nodejs,检测 nodejs 环境(node -v). 2.安装vue-cli脚手架npm install vue-cli -g 3.在电脑的某个盘中创建项目,之后进入该项目. 4.初始 ...