在传统桌面项目中,进度条随处可见,但作为一个很好的用户体验,却没有在如今主流的B/S程序中得到传承,不能不说是个遗憾。这个遗憾并非WEB程序不支持进度条,很大的原因应该是我们由于种种麻烦懒的去实现。前段时间由于新项目等待客户验收,有点闲暇时间,于是突发奇想决定给新系统的所有导出功能添加进度提示,替换现正使用的只简单显示一个Loading图片作为提示的方法,于是有了本文。
实现的思路很简单:服务器端收到客户端一个需要较长时间执行的任务 -> 服务器端开始执行这个任务并创建一个 Progress 状态,保存在 Cache 中,在任务执行过程中,不断更新进度 -> 同时,客户端新取一个线程(异步),每隔0.5秒(经过测试,0.5秒是一个比较好的时间,既不容易造成客户端网络拥堵,也能带来相当好的用户体验)访问一次服务器以获得该任务的进度并呈现给终端用户。
下面是本人的实现方法,它能支持所有需要精确计算进度的任务,觉得有一定的参考性,前后台代码分别采用 Javascript 和 C# 实现,分享给大家。
服务器端我们需要做 2 件事情:进度管理类和一个供客户端查询状态的页面(采用 Handler实现)。
首先是进度管理类,主要用于记录任务总数和当前已经完成的数目,同时自行管理缓存状态,以方便客户端随时访问。代码如下:
using Cache;
using System;
namespace RapidWebTemplate.WebForm {
///
/// 服务器事件进度服务
///
public sealed class ProgressService {
// 缓存保存的时间,可根据自己的项目设置
private const int CACHE_SECONDS = 600;
// 任务唯一ID
private string _key = null;
private ProgressService() { }
///
/// 获取或设置总进度
///
public int Total { get; set; }
///
/// 获取或设置已经完成的进度
///
public int Elapsed { get; set; }
///
/// 获取已经完成的进度百分比
///
public byte ElapsedPercent {
get {
if (Finished) { return 100; }
double d = (double)Elapsed / (double)Total * 100d;
var tmp = Convert.ToInt32(M