当前位置:主页 > 学服务器 > Linux >

Http批量异步发送和数据保存
栏目分类:Linux   发布日期:2020-03-11  来源:趣素材网 - www.pic83.com 浏览次数:

先说需求。 有个服务程序定时扫描指定文件夹下一个所有文件,文件包含了多个用户(客户)信息及对应的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 = 0; i < 10; i++)
            {
                //用线程池去执行http任务
                ThreadPool.QueueUserWorkItem(GeneralHttpTest,i);
            }
            //延时是为了等待上面的线程跑完 不影响我们观看后续测试数据
            Thread.Sleep(5000);
            Console.WriteLine("Thread");
            for (int i = 0; i < 10; i++)
            {
                //用线程去执行http任务
                Thread th = new Thread(new ParameterizedThreadStart(GeneralHttpTest));
                th.Start(i);
            }
            Thread.Sleep(5000);
            Console.WriteLine("Task");
            for (int i = 0; i < 10; i++)
            {
                //用task去执行http任务
                new Task(() =>
                {
                    GeneralHttpTest(i);
                }).Start();
            }
            Console.ReadKey();
        }
        static void GeneralHttpTest(object i)
        {
            //请求http 并打印http返回结果
            int status = 0;
            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.。

相关热词:

Copyright © 2010-2020 www.pic83.com. 趣素材网 版权所有   粤ICP备12084032号-5  壁纸设计 | 酷站欣赏 | 绘画艺术 | 平面设计 | 交互设计 | 3D艺术 | 摄影艺术 |
原创作品 经验分享 设计素材 佳作欣赏 装饰设计 设计学院 学服务器 系统下载 电脑教程