Web页面实现后台数据处理进度与剩余时间的展示

Web页面实现后台数据处理进度与剩余时间的显示

    1、页面后台代码添加如下静态变量:

/// <summary>
/// 总数
/// </summary>
private static double total = 0;
/// <summary>
/// 当前进度
/// </summary>
private static int cur = 0;
/// <summary>
/// 错误信息
/// </summary>
private static string errMsg = string.Empty;
/// <summary>
/// 开始时间
/// </summary>
private static DateTime startTime = DateTime.Now;

    2、在处理数据的开始,初始化total和startTime变量:

total = int.Parse(dataSet.Tables[0].Rows[0][0].ToString());
startTime = DateTime.Now;

    3、在处理数据过程中,不断累加cur:

cur++;

    4、前端每隔500毫秒获取进度:

<script type="text/javascript">
    //更新进度
    function refreshProcess() {
        var itv = setInterval(function () {
            $.ajax({
                url: "ExcelLeadIn.aspx?action=getProcess&t=" + new Date().valueOf(),
                type: "POST",
                data: {},
                success: function (data) {
                    if (data == "导入进度:100.00%") {
                        clearInterval(itv);
                        $("#msg").html(data);
                        alert("导入成功");
                    } else {
                        if (data.indexOf("错误:") == 0) {
                            clearInterval(itv);
                        }
                        $("#msg").html(data);
                    }
                }
            });
        }, 500);
    }
    refreshProcess();
</script>

    5、后台计算进度:

protected void Page_Load(object sender, EventArgs e)
{
    string result = string.Empty;

    if (Request["action"] == "getProcess")
    {
        try
        {
            if (string.IsNullOrEmpty(errMsg))
            {
                if (total == 0)
                {
                    result = "导入进度:0%";
                }
                else
                {
                    DateTime now = DateTime.Now;
                    TimeSpan ts = now - startTime;

                    string time = string.Empty;
                    double per = cur / total;
                    if (per > 0)
                    {
                        double totalSeconds = ts.TotalSeconds / per - ts.TotalSeconds;
                        if (totalSeconds > 60)
                        {
                            time = (int)Math.Round(totalSeconds / 60) + "";
                        }
                        else
                        {
                            time = (int)Math.Round(totalSeconds) + "";
                        }
                    }

                    string percent = (cur / total * 100).ToString("0.00");
                    if (percent == "100.00")
                    {
                        cur = 0;
                        total = 0;
                        result = string.Format("导入进度:{0}%", percent);
                    }
                    else
                    {
                        result = string.Format("导入进度:{0}%,剩余时间:{1}", percent, time);
                    }
                }
            }
            else
            {
                result = "错误:" + errMsg;
            }
        }
        catch (Exception ex)
        {
            result = "错误:" + ex.Message;
        }
    }

    if (!string.IsNullOrEmpty(result))
    {
        Response.Write(result);
        Response.End();
    }
}

    效果图(文字错了,不是“导入进度”,而是“数据处理进度:”):

Web页面实现后台数据处理进度与剩余时间的展示

 

修改以支持多用户同时导入:

    1、页面后台代码添加如下静态变量:

/// <summary>
/// 总数
/// </summary>
private static Dictionary<string, double> total = new Dictionary<string, double>();
/// <summary>
/// 当前进度
/// </summary>
private static Dictionary<string, int> cur = new Dictionary<string, int>();
/// <summary>
/// 错误信息
/// </summary>
private static Dictionary<string, string> errMsg = new Dictionary<string, string>();
/// <summary>
/// 开始时间
/// </summary>
private static Dictionary<string, DateTime> startTime = new Dictionary<string, DateTime>();

#region 总数
private void setTotal(string userId, double value)
{
    if (total.ContainsKey(userId))
    {
        total[userId] = value;
    }
    else
    {
        total.Add(userId, value);
    }
}
private double getTotal(string userId)
{
    if (total.ContainsKey(userId))
    {
        return total[userId];
    }
    else
    {
        return 0;
    }
}
#endregion

#region 当前进度
private void addCur(string userId)
{
    if (cur.ContainsKey(userId))
    {
        cur[userId]++;
    }
    else
    {
        cur.Add(userId, 1);
    }
}
private void setCur(string userId, int value)
{
    if (cur.ContainsKey(userId))
    {
        cur[userId] = value;
    }
    else
    {
        cur.Add(userId, value);
    }
}
private int getCur(string userId)
{
    if (cur.ContainsKey(userId))
    {
        return cur[userId];
    }
    else
    {
        return 0;
    }
}
#endregion

#region 错误信息
private void setErrMsg(string userId, string value)
{
    if (errMsg.ContainsKey(userId))
    {
        errMsg[userId] = value;
    }
    else
    {
        errMsg.Add(userId, value);
    }
}
private string getErrMsg(string userId)
{
    if (errMsg.ContainsKey(userId))
    {
        return errMsg[userId];
    }
    else
    {
        return string.Empty;
    }
}
#endregion

#region 开始时间
private void setStartTime(string userId, DateTime value)
{
    if (startTime.ContainsKey(userId))
    {
        startTime[userId] = value;
    }
    else
    {
        startTime.Add(userId, value);
    }
}
private DateTime getStartTime(string userId)
{
    if (startTime.ContainsKey(userId))
    {
        return startTime[userId];
    }
    else
    {
        return DateTime.Now;
    }
}
#endregion

    2、在处理数据的开始,初始化total和startTime变量:

setTotal(loginUser.USER_ID, int.Parse(dataSet.Tables[0].Rows[0][0].ToString())); //总数
setStartTime(loginUser.USER_ID, DateTime.Now); //开始时间

    3、在处理数据过程中,不断累加cur:

addCur(loginUser.USER_ID); //进度累加

    4、前端每隔500毫秒获取进度:

<script type="text/javascript">
    //更新进度
    function refreshProcess() {
        var itv = setInterval(function () {
            $.ajax({
                url: "ExcelLeadIn.aspx?action=getProcess&t=" + new Date().valueOf(),
                type: "POST",
                data: {},
                success: function (data) {
                    if (data == "导入进度:100.00%") {
                        clearInterval(itv);
                        $("#msg").html(data);
                        alert("导入成功");
                    } else {
                        if (data.indexOf("错误:") == 0) {
                            clearInterval(itv);
                        }
                        $("#msg").html(data);
                    }
                }
            });
        }, 500);
    }
    refreshProcess();
</script>

    5、后台计算进度:

protected void Page_Load(object sender, EventArgs e)
{
    string result = string.Empty;

    if (Request["action"] == "getProcess")
    {
        try
        {
            LoginEntity loginUser = (LoginEntity)this.Session[BasePage.LOGIN_USER_KEY];
            string userId = loginUser.USER_ID;
            if (string.IsNullOrEmpty(getErrMsg(userId)))
            {
                if (getTotal(userId) == 0)
                {
                    result = "导入进度:0%";
                }
                else
                {
                    DateTime now = DateTime.Now;
                    TimeSpan ts = now - getStartTime(userId);

                    string time = string.Empty;
                    double per = getCur(userId) / getTotal(userId);
                    if (per > 0)
                    {
                        double totalSeconds = ts.TotalSeconds / per - ts.TotalSeconds;
                        if (totalSeconds > 60)
                        {
                            time = (int)Math.Round(totalSeconds / 60) + "";
                        }
                        else
                        {
                            time = (int)Math.Round(totalSeconds) + "";
                        }
                    }

                    string percent = (getCur(userId) / getTotal(userId) * 100).ToString("0.00");
                    if (percent == "100.00")
                    {
                        setCur(userId, 0);
                        setTotal(userId, 0);
                        result = string.Format("导入进度:{0}%", percent);
                    }
                    else
                    {
                        result = string.Format("导入进度:{0}%,剩余时间:{1}", percent, time);
                    }
                }
            }
            else
            {
                result = "错误:" + errMsg;
            }
        }
        catch (Exception ex)
        {
            result = "错误:" + ex.Message;
        }
    }

    if (!string.IsNullOrEmpty(result))
    {
        Response.Write(result);
        Response.End();
    }
}

 

2楼guan-zo
不实用,一个处理请求这么多次!
Re: 秋荷雨翔
@guan-zo,引用不实用,一个处理请求这么多次!,你可以1秒执行一次或2秒执行一次啊,如果你想20秒执行一次,那么你怎么实时获取进度?
1楼guan-zo
使用 StateServer 保存 Session,很稳定,实质就是把Session 存放在一个单独的进程里
Re: 秋荷雨翔
@guan-zo,引用使用 StateServer 保存 Session,很稳定,实质就是把Session 存放在一个单独的进程里,mark,下次做同类功能再改。