Http批量异步发送和数据保存
先说需求。
有个服务程序定时扫描指定文件夹下一个所有文件,文件包含了多个用户(客户)信息及对应的http发送地址和发送数据。现在该服务程序需要提取这些用户信息,然后批量进行发送;发送完后需要将http返回结果和当前用户对应上;到最后进行批量保存。当然批量保存是为了减少数据库压力。
这里的批量数据保存使用的sqlbulkcopy 在此就不做介绍了。
这里谈谈自己最开始和最后实现的思路及方法。
针对这一需求我的确也是第一次经历,所以经验很少。
看到异步发送,我首先想到了用.Net 4.0里面的Task,因为task非常简单易用,代码也更加直观而且还是基于线程池的。
谈谈我看到的task和thread的区别:
同一个任务我用Task、Thread、ThreadPool进行比较下。
测试代码:
static void Main(string[] args)
{
Console.WriteLine("ThreadPool");
for (int i = ; i < ; i++)
{
//用线程池去执行http任务
ThreadPool.QueueUserWorkItem(GeneralHttpTest,i);
}
//延时是为了等待上面的线程跑完 不影响我们观看后续测试数据
Thread.Sleep();
Console.WriteLine("Thread");
for (int i = ; i < ; i++)
{
//用线程去执行http任务
Thread th = new Thread(new ParameterizedThreadStart(GeneralHttpTest));
th.Start(i);
}
Thread.Sleep();
Console.WriteLine("Task");
for (int i = ; i < ; i++)
{
//用task去执行http任务
new Task(() =>
{
GeneralHttpTest(i);
}).Start();
}
Console.ReadKey();
}
static void GeneralHttpTest(object i)
{
//请求http 并打印http返回结果
int status = ;
string respStr = SimpleHttpHelper.HttpGetRequest(url, out status);
Console.WriteLine(i + " " + respStr);
}
结果:

从这个结果看 我感觉task里面有个任务缓冲区;它等到缓冲区满了或者间隔时间到了则开始一起执行所有任务。我们循环10次去调用task 每循环一次传递一下当前循环的值。在每次循环的时候task好像没有立即去执行我们的方法,而是等到循环完了 才一起去执行所有方法。所以看到了 每次循环的值 都是10。
当然这里可以用线程安全的一些类去代替i做这个值传递 比如ConcurrentBag、ConCurrentDictionay等等。这个时候用task能够保证传递数据的一致性。
上面说的缓冲区这是我个人的一种描述;或许我这样去理解也不是很对,因为我对task没有很深的研究。
最开始我是用的task进行批量发送,用task的 WaitAll进行等待所有任务完成再进行数据保存。这样最后发现的弊端就是,我们要等待当前这一批(即一个文件内的数据)数据完成后才能进行下一批数据的发送。这样就会造成性能的损耗,当我有几十几千批数据需要发送的时候 这样速度就显的非常之慢。
后来一些原因我没用task进行异步发送了,后来直接使用 HttpWebRequest的异步执行方法 BeginGetResponse。
HttpWebRequest异步发送可以看我的《Http异步发送之HttpWebRequest的BeginGetResponse》这里面有我封装的代码。
何时对数据进行批量保存
我最开始的保存思路是将每条数据都添加到一条list ,因为要获取http返回的结果,所以添加时 是在异步返回结果后进行添加。然后每次异步发送时附带上本次总数据有多少,每次请求回调后,对比下当前list总数和传递时带过来的总数比较是否相等。相等则直接保存数据。这样有个弊端如果中间某个线程丢失,这样list总数和我们每次请求附带的总数就不一致了;这样则会导致数据对不上永远不会保存了。
最后的方案还是用队列实现 .Net里面的Queue或者线程安全的ConcurrentQueue;每次将数据都添加到队列里,然后定时从队列里取数据然后进行保存。队列的好处就在于数据的添加和移除互不影响。在多线程里面对数据的临时存储建议用队列 少用list.。
Http批量异步发送和数据保存的更多相关文章
- socket 异步 发送 接收 数据
Socket socketClints = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); / ...
- Appcan开发笔记:结合JQuery的$.Deferred()完善批量异步发送
appcan的 uexXmlHttpMgr.send 或者 appcan.ajax无法同步请求(没有找到这个属性),只能异步,造成循环多次提交时由于延迟或网络堵塞等原因无法同步响应,导致提交顺序混乱, ...
- 16 react 发送异步请求获取数据 和 使用Redux-thunk中间件进行 ajax 请求发送
1.发送异步请求获取数据 1.引入 axios ( 使用 yarn add axios 进行安装 ) import axios from 'axios'; 2. 模拟 在元素完成挂载后加载数据 并初始 ...
- Django中数据传输编码格式、ajax发送json数据、ajax发送文件、django序列化组件、ajax结合sweetalert做二次弹窗、批量增加数据
前后端传输数据的编码格式(contentType) 提交post请求的两种方式: form表单 ajax请求 前后端传输数据的编码格式 urlencoded formdata(form表单里的) ja ...
- 利用Excel批量高速发送电子邮件
利用Excel批量高速发送电子邮件,分两步: 1. 准备待发送的数据: a.) 打开Excel,新建Book1.xlsx b.) 填入以下的内容, 第一列:接收人,第二列:邮件标题,第三列:正文,第四 ...
- Http异步发送之HttpWebRequest的BeginGetResponse
关于http异步发送,一开始我的做法都是用thread或者task去完成的:后来发现HttpWebRequest本身就提供一个异步的方法. 总感觉.Net自己提供的异步方法可能要优于我们自己用线程去实 ...
- python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)
昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...
- 关于高并发下kafka producer send异步发送耗时问题的分析
最近开发网关服务的过程当中,需要用到kafka转发消息与保存日志,在进行压测的过程中由于是多线程并发操作kafka producer 进行异步send,发现send耗时有时会达到几十毫秒的阻塞,很大程 ...
- 【小梅哥FPGA进阶教程】串口发送图片数据到SRAM在TFT屏上显示
十五.串口发送图片数据到SRAM在TFT屏上显示 之前分享过rom存储图片数据在TFT屏上显示,该方法只能显示小点的图片,如果想显示TFT屏幕大小的图片上述方法rom内存大小不够.小梅哥给了个方案,利 ...
随机推荐
- python 读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal multibyte sequence
python读取文件时提示"UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 205: illegal m ...
- 关于jQuery插件imgAreaSelect基础讲解
关于ImgAreaSelect, 是一jQuery插件,它支持用户通过鼠标拖曳选择图片的一部分,如图片拖曳.图片编辑等~~来具体看一下 1.先下载imgAreaSelect插件 下载地址: 英文:h ...
- HourRank 20
第一题略 第二题组合数学 s1 = min(cnt['a'],cnt['b']), s2 = min(cnt['c'],cnt['d']), b1 = max(cnt['a'],cnt['b']), ...
- maven如何修改本地仓库与中央仓库
摘要: 运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的.如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件. 什么是Maven仓库 在不用M ...
- Adobe After Effect CC2017 for Mac
前段时间学习使用 Lottie 制作炫酷的动画,需要 Adobe After Effect 安装 bodymovin 插件,然后导出动画的 json 文件.尝试安装 AE 工具.网上查找 史蒂芬周的博 ...
- kafka 自定义分区器
package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.Partitioner; import org.a ...
- 关于图的顶点染色问题的各种算法的C++实现之初探(一)——引言与简介
我是一个数学工作者,专业方向是图论.研究图论已经十年有余.一个月前,一个偶然的机会让我萌生了一个念头,那就是我想尝试用C++写出我所学过的图论方面的算法.作为一个数学工作者,过去一直是纸上谈兵,我之前 ...
- 并行类加载与OSGI类加载
这回来分析一下OSGI的类加载机制. 先说一下OSGI能解决什么问题吧. 记得在上家公司的时候,经常参与上线.上线一般都是增加了一些功能或者修改了一些功能,然后将所有的代码重新部署.过程中要将之前的服 ...
- 客户端存储 API
介绍两个在客户端存储数据的 API localStorage与sessionStorage 两个都是window对象的属性,利用这两个属性,可以在客户端存储一些数据 相比cookie,这种存储方式的优 ...
- springcloud(八):配置中心服务化和高可用
在前两篇的介绍中,客户端都是直接调用配置中心的server端来获取配置文件信息.这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由,serve ...