耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案

简介: 需求:B/S结构的系统里,用户点一个按钮系统开始发送上千封邮件,要求把发送信息(发送成功数,失败数,剩余数量...)动态实时的反馈给客户.   分析和实施过程当中遇到的问题:     一:最低级的问题由于客户催的紧,发邮件的核心代码写好后就开始给他使用了,当时系统还没上AJAX.

需求:
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日为了阅读方便,我对文章做了一些修改,主要内容未变

目录
相关文章
|
19天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
30 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
17天前
|
弹性计算 监控 容灾
阿里云ECS提供强大的云上灾备解决方案,通过高可用基础设施、多样的数据备份方式及异地灾备服务,帮助企业实现业务的持续稳定运行
在数字化时代,企业对信息技术的依赖加深,确保业务连续性至关重要。阿里云ECS提供强大的云上灾备解决方案,通过高可用基础设施、多样的数据备份方式及异地灾备服务,帮助企业实现业务的持续稳定运行。无论是小型企业还是大型企业,都能从中受益,确保在面对各种风险时保持业务稳定。
34 4
|
1月前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
2月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
152 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
2月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
169 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
1月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
349 2
|
2月前
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
81 1
|
2月前
|
网络协议 Unix Linux
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
|
2月前
|
安全 区块链 数据库
|
2月前
|
编解码 弹性计算 运维
AWS无服务器直播解决方案
AWS无服务器直播解决方案