耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案
需求:
B/S结构的系统里,用户点一个按钮系统开始发送上千封邮件,要求把发送信息(发送成功数,失败数,剩余数量...)动态实时的反馈给客户.
分析和实施过程当中遇到的问题:
一:最低级的问题
由于客户催的紧,发邮件的核心代码写好后就开始给他使用了,当时系统还没上AJAX.
最初的问题是一点按钮过不了几分钟就页面超时(要想页面不超时必须定时给页面输出一些东西),
搞定了页面超时的问题然后就是服务器IIS超时
设置了IIS超时时间就又SQL连接超时
最后寻思这样下去总不是个办法
决定上ajax(正如大家想的一样)
二:开始想到了ajax
上ajax又碰到一个问题
ICallbackEventHandler只提供了两个方法,
一个是被客户端触发的服务器端事件,
一个是服务器端事件完成后的反馈事件
两个事件是顺序发生的,
我如果在一个事件中执行发送邮件的过程,
我就不能在这个事件中把中间过程的信息反馈给客户
我的两个需求必须同时进行!
我甚至想到:当用户点按钮的时候同时触发ajax事件和postback事件,
多么愚蠢的idea啊(回发了还怎能异步刷新)
最后:多方求助+苦思冥想最后得出两种解决方案
1.通过ajax每次发送一定数量的邮件
用javascript循环把邮件地址发送给服务器端(以ajax方式),
每循环一次给服务器端10条信息,
服务器端把这10个邮件发完之后,反馈客户端一次
客户端通过js更新提示信息(已经发完十封了)
然后进入下一次ajax循环
2.ajax调用服务器端事件,在服务器端事件里使用多线程技术
当用户点按钮触发了ajax服务器端事件后,
在这个事件里我建立了两个线程
一个线程开始发送邮件,另一个线程负责返回信息
因为要实时的返回信息,
所以这个ajax事件肯定是定时调用的.(我是每4秒获取一下服务器端的信息)
服务器端事件开始执行,
先判断发邮件的线程是否已经开始了,
如果没开始就建立发邮件的线程,
并执行线程
如果开始了(那么说明这个调用肯定不是第一次调用)
就执行反馈信息的代码
两种方案都是可行的,我最终选择了第二种
想法随好,在实施过程中又碰到了N多问题
三.实施过程中的问题
1.假如在发送过程中用户出现了断网,或者不小心关闭了页面,我怎么让他下次登陆的时候继续发送.
在这里我想到了消息队列,事务等,最终的解决方案是
开始发邮件前先把所有待发的邮件存储到数据库的一个临时表里去,
发一封删除一条记录,
pagelodad里检测该表是否有记录,
如果有记录就直接发送该表里的邮件(也就是尚未完成的邮件)
这里可以用Page.ClientScript.RegisterStartupScript注册一个客户端事件调用我们的ajax函数
2.线程的参数问题
发送邮件的线程方法是肯定需要参数的,然而new Thread(new ThreadStart());创建线程的又不允许给线程传参数,
这个问题没有困绕我很久,因为网上有很多解决方案,比如建立一些public的变量或者属性
我用的是另外一种办法,先建立一个对象,然后给这个对象的属性负值(这就是我的参数啦)
然后创建线程的时候线程的方法是这个对象的一个方法sendmail_thread = new Thread(new ThreadStart(sendobj.sendmail_xuan));
3.线程开始状态判断的误区
线程有一个ThreadState属性,我不建议用这个属性的IsAlive判断线程是否开始.
因为代码执行到sendmail_thread = new Thread(new ThreadStart(sendobj.sendmail_xuan));这句后,
线程并不一定处于IsAlive状态,因为他要等服务器的CPU给他分配时间片(具体的我就不说了)
我是用session判断的
4.还是线程的问题
当用户执行了操作,有可能发送邮件的线程还没有开始,而ajax已经去取返回信息了.
(如果计算发送成功率,有可能造成除以0的错误)
或者邮件发送线程已经完成了操作,但ajax还一直在那取后端的反馈信息
(如果反馈发送消耗时间,有可能时间会一直增长)
人们都说网页上的多线程不好搞(每个访问就有可能造成一个线程)
果然如此啊,我这里还没考虑高并发的问题,
然而上面说的那两个问题都不是硬伤,
想想办法还是可以"掩饰"过去的
文章就写到这,我没有公布原代码,只是写了一些思想和解决方法
实在是我这个案例有点偏了.大家如果一定要原代码,那么就在此文章下留言吧
如果要的人超过10个我就写这个文章的续
另:系统开发过程中得到了Jeffrey Zhao joseph.zhu(asp.net第一步的作者) 南洋 的帮助 在此表示感谢
8.19日为了阅读方便,我对文章做了一些修改,主要内容未变
耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案相关推荐
- 开发那些事儿:如何解决RK芯片视频处理编解码耗时很长的问题?
流媒体视频直播包括以下几个步骤:采集->处理->编码和封装->推流到服务器->服务器流分发->播放器流播放. 在流媒体处理编码的过程中,会有硬解码和软解码两种播放方式.两 ...
- 在Servlet中向客户端写Cookie信息
应用Servlet API中提供的Cookie类,用户把表单信息提交给Servlet后,在Servlet中获取用户请求的信息并添加到Cookie对象中,再通过HttpServletResponse对象 ...
- 耗时很长的程序忘加nohup就运行了怎么办?
在NGS基础:测序原始数据下载一文中提到可以使用SRA-toolkit中的命令fastq-dump从NCBI下载原始测序数据,命令如下. nohup fastq-dump -v --split-3 - ...
- 送书 | 耗时很长的程序忘加nohup就运行了怎么办?
在NGS基础:测序原始数据下载一文中提到可以使用SRA-toolkit中的命令fastq-dump从NCBI下载原始测序数据,命令如下. nohup fastq-dump -v --split-3 - ...
- 解决magento保存产品时耗时很长的问题
以前我在更新产品属性值(拿price为例)的时候,通常会这样做: foreach($product_ids as $id){$product = Mage::getModel('catalog/pro ...
- linux sendto 速度慢,UDP Socket 广播中sendto()耗时过长
UDP Socket 广播中,sendto()将数据发送到一个结尾为"255"的IP地址,应用中发现sendto()函数耗时过长.参考了"http://topic.csd ...
- linux udt 源码,UDT linux下关闭链接耗时过长
不知道使用UDT的人多不多,很大可能会石沉大海啊 ========================================================= 我在使用UDT库的时候,linux ...
- 温故而知新,UI学习中的大部分控件及常用的基础都整理了一下,很长~~~~~~~~~很长!!!!!!!...
生命周期,生命周期,生命周期,重要的事要说三遍,战五渣的我最常用的好像只有Viewwillappear吧 - (BOOL)application:(UIApplication *)applicatio ...
- 关于页面请求发起后,通过F12查看到,被挂起页面中stalled花费很长时间问题的追查...
2019独角兽企业重金招聘Python工程师标准>>> 请求刚一发出,timing中显示是这样的 有时候过了几十秒之后才响应返回,页面加载完成. 已下内容纯粹是转载,只为做个记录.方 ...
最新文章
- POJ 3111 K Best (最大化平均值,贪心 二分)难度⭐⭐⭐
- python3 collections模块_Python3之collections模块
- python 还原九宫格图片_用Python做一个好玩的朋友圈九宫格抽奖
- Linux学习之系统编程篇:信号的基本概念
- 牛客16494 生活大爆炸版石头剪刀布
- Maven:IDEA 使用maven 下载源码包
- 【sklearn第三讲】数据预处理
- HTML期末学生大作业-最新QQ音乐、网易云音乐、酷狗音乐、虾米音乐、咪咕音乐网站html+css+javascript
- 怎么把Word转PDF格式?分享几种好用的转换方法
- ElasticSearch版本与Jar包冲突
- 理财产品的收益率也抵不上通货膨胀
- 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试...
- selenum登录163邮箱
- 全球最大湾区|微信大数据:《粤港澳大湾区智慧生活圈报告》
- uniapp 原生js实现公历转农历
- Java8 通过foreach 遍历List,同时输出下标
- 邮箱容量满了怎么办?我的邮箱容量快满了如何解决?
- 企业微信可以自动上班打卡吗?
- 谁是世界上最好的编程语言?--编程语言70年浅谈
- python--os.chdir() 方法 切换当前工作路径
热门文章
- 父窗口控制弹出窗口快捷键ctrl+c关闭
- 取子字符串的两种情形的解决办法(c#)
- 2014西安 H 有向图博弈 UVALive-7042
- 京东方拟收购法国零售物联网领域公司50.1%以上股份
- 编程之美初赛第一场--焦距
- 4月全球操作系统市场份额:Win 7份额连续4月上涨
- Python 2.7终结于7个月后,这是你需要了解的3.X炫酷新特性
- C++调用matlab char16_t 重复定义
- 掌握管理Linux磁盘和分区的方法 创建并挂载文件系统以及 创建并管理LVM
- Maven学习教程(六)