在学习使用MVC的过程中,会经常遇到从Excel文件导入到数据库的需求,数据量也还不小,后台处理经常需要较长时间,这时候就需要一个进度条来显示执行状态了。
通过百度“MVC PROGRESS”或者“MVC 进度条”,找到的结果都不是管用的。大多数都会出现这篇博文中所说的问题:
https://www.cnblogs.com/crazyguo/p/4878345.html,
“进度一直不提示,直到数据上传成功了,提示显示100%“。调试过程发现,
线程虽然将读取进度条的命令安排下去了,但是只给了面子没给里子,读取进度条的代码一条都不会去执行!通过把休眠时间强制改成System.Threading.Thread.Sleep(500),原先总共只需要1分钟不到的后台任务,直到约2分钟之后才有可能会去显示进度条数据。这样就失去了进度条的意义。
最后,找到这个老外的网站
https://www.codeproject.com/Articles/1124691/SignalR-Progress-Bar-Simple-Example-Sending-Live-D
才最终解决了问题。
我们先创建一个MVC项目,然后开始测试我们的进度条。
第 1 步,通过 NuGet 包管理器,安装 Microsoft.AspNet.SignalR
第 1 步,通过 NuGet 包管理器,安装 Microsoft.AspNet.SignalR
第
2
步,修改
Startup.cs
,在倒数第
3
个大括号之前插入代码:
app.MapSignalR();
第
3
步,在项目添加文件夹
Hubs
,并在其下添加类文件
ProgressHub.cs
下面是ProgressHub.cs的全部代码:
using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcSinalRProgressBar.Hubs
{
public class ProgressHub : Hub
{
}
public class Functions
{
public static void SendProgress(string progressMessage, int progressCount, int totalItems)
{
//IN ORDER TO INVOKE SIGNALR FUNCTIONALITY DIRECTLY FROM SERVER SIDE WE MUST USE THIS
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
//CALCULATING PERCENTAGE BASED ON THE PARAMETERS SENT
//var percentage = (progressCount * 100) / totalItems;
//PUSHING DATA TO ALL CLIENTS
hubContext.Clients.All.AddProgress(progressMessage, progressCount, totalItems);
}
}
}
第4步,修改模板_Layout.cshtml,或者其他页面也行,在Head部分插入以下代码:
<link rel="stylesheet" href="~/Content/bootstrap.min.css" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.2.min.js" type="text/javascript"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
// Reference the auto-generated proxy for the hub.
var progress = $.connection.progressHub;
console.log(progress);
// Create a function that the hub can call back to display messages.
progress.client.AddProgress = function (message, progressCurrent, progressTotal) {
var myDate = new Date();
$("#endTime").val(myDate.toLocaleString());
var value = parseInt(progressCurrent * 100 / progressTotal);
changeProgUI(value, progressCurrent, progressTotal);
};
$.connection.hub.start().done(function () {
var connectionId = $.connection.hub.id;
console.log(connectionId);
});
});
function changeProgUI(value, progressCurrent, progressTotal) {
$("#prog").css("width", value + "%").text(value + "% (" + progressCurrent + "/" + progressTotal + ")");
if (value >= 0 && value <= 30) {
$("#prog").addClass("progress-bar-danger");
}
else if (value >= 30 && value <= 60) {
$("#prog").removeClass("progress-bar-danger");
$("#prog").addClass("progress-bar-warning");
}
else if (value >= 60 && value <= 90) {
$("#prog").removeClass("progress-bar-warning");
$("#prog").addClass("progress-bar-info");
}
else if (value >= 90 && value < 100) {
$("#prog").removeClass("progress-bar-info");
$("#prog").addClass("progress-bar-success");
}
}
</script>
第5步,在Body部分插入以下代码:
<div class="form-group">
<div class="row">
<div class="progress progress-striped active" id="proges">
<div id="prog" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%;">
<span id="proglabel">正在启动,请稍后......</span>
</div>
</div>
</div>
<div class="col-sm-2"></div>
<div class="col-sm-10">
<div class="row">
<label class="pos-rel">
<span class="lbl">导入耗用时间:从</span>
<input type="text" id="startTime" disabled />
<span class="lbl">至</span>
<input type="text" id="endTime" disabled />
</label>
</div>
</div>
</div>
第6步,后台控制器,添加引用usingMvcSinalRProgressBar(项目名).Hubs;
第7步,在长时间后台任务的循环语句中,插入以下代码
Thread.Sleep(1);
Functions.SendProgress("Process in progress...", i, itemsCount);
大功告成!
要点提示,这个包又不能使用最新的jquery版本!我安装的是VS2015,默认的jquery版本是1.10.2,能管用!
<link rel="stylesheet" href="~/Content/bootstrap.min.css" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.2.min.js" type="text/javascript"></script>
<script src="~/signalr/hubs"></script>