head> <title>Index</title> <style type="text/css"> #statusBorder { position:relative; height:5px; 100px; border:solid 1px gray; display:none; } #statusFill{ position:absolute; top:0; left:0; 0px; background-color:Blue; height:5px; } </style> <script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> <script type="text/javascript"> var uniqueId = " @Guid.NewGuid().ToString()"; $(document).ready(function (event) { $('#startProcess').click(function () { $.post("Home/StartLongRunningProcess",{ id: uniqueId }, function (data) { if (data = "null") { alert("文件为空!"); } else { $('#statusBorder').show(); getStatus(); } }, "multipart/form-data"); event.preventDefault; }); }); function getStatus() { var url = 'Home/GetCurrentProgress/' + uniqueId; $.get(url, function (data) { if (data != "100") { $('#status').html(data); $('#statusFill').width(data); window.setTimeout("getStatus()", 100); } else { $('#status').html("Done"); $('#statusBorder').hide(); alert("文件保存成功"); }; }); } </script> </head> <body> <div> <div id="status"> </div> <h2>@Html.Encode(ViewData["Message"]) </h2> <div> <input id="File1" type="file" name="file" /> <input id="startProcess" type="submit" value="提交" /> </div> <br /> <div id="statusBorder"> <div id="statusFill"> </div> </div> </div> </body> </html>
Action代码
public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { ViewData["Message"] = "Ajax Progress Bar Example"; return View(); } delegate string ProcessTask(string id); MyLongRunningClass longRunningClass = new MyLongRunningClass(); public ContentResult StartLongRunningProcess(string id) { var file=Request.Files["file"]; if (file != null) { file.SaveAs(Server.MapPath("~/Content/" + file.FileName)); longRunningClass.Add(id); ProcessTask processTask = new ProcessTask(longRunningClass.ProcessLongRunningAction); processTask.BeginInvoke(id, new AsyncCallback(EndLongRunningProcess), processTask); return Content("ok"); } else { return Content("null"); } } public void EndLongRunningProcess(IAsyncResult result) { ProcessTask processTask = (ProcessTask)result.AsyncState; string id = processTask.EndInvoke(result); longRunningClass.Remove(id); } public ContentResult GetCurrentProgress(string id) { this.ControllerContext.HttpContext.Response.AddHeader("cache-control", "no-cache"); var currentProgress = longRunningClass.GetStatus(id).ToString(); return Content(currentProgress); } public ActionResult Upload(HttpPostedFileBase[] fileToUpload) { ViewBag.Message = "File(s) uploaded successfully"; return RedirectToAction("Index"); }
cs代码
public class MyLongRunningClass { private static object syncRoot = new object(); private static IDictionary<string, int> ProcessStatus { get; set; } public MyLongRunningClass() { if (ProcessStatus == null) { ProcessStatus = new Dictionary<string, int>(); } } public string ProcessLongRunningAction(string id) { for (int i = 1; i <= 100; i++) { Thread.Sleep(100); lock (syncRoot) { ProcessStatus[id] = i; } } return id; } public void Add(string id) { lock (syncRoot) { ProcessStatus.Add(id,0); } } public void Remove(string id) { lock (syncRoot) { ProcessStatus.Remove(id); } } public int GetStatus(string id) { lock (syncRoot) { if (ProcessStatus.Keys.Count(x => x == id) == 1) { return ProcessStatus[id]; } else { return 100; } } } }