나는 Jason의 의견을 따르고 별도의 ajax 호출을 사용하여 폴링을 수행하고 간헐적 인 응답을받을 수 있습니다.
아래 코드에서 서버에 jquery.form 플러그인을 사용하여 파일을 업로드하고 컨트롤러 수준에서 장기 실행 작업을 수행하려고합니다. 사용자에게 진행 상황을 표시하기 위해 폴링 개념을 사용하여 장시간 실행되는 작업의 상태를 확인합니다. 여기
는
ASP 코드입니다.NET HTML :
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="row">
<div class="col-xs-12">
<div class="alert alert-warning">This page uses jquery.form plugin to upload</div>
</div>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="NoFormContentPlaceHolder" runat="server">
<div class="row">
<div class="col-xs-12">
<form id="ImportFileForm" method="post" action="api/FileUpload/Upload" enctype="multipart/form-data">
<div class="col-xs-3">
<input type="file" id="ImportFile" name="ImportFile" accept="*.xlsx" class="col-xs-12 file-selector" />
</div>
<div class="col-xs-1">
<button class="btn btn-danger btn-xs" id="ImportFileBtn" type="submit" title="Import"><span class="glyphicon glyphicon-import"></span>Import</button>
</div>
</form>
</div>
</div>
<div class="row row-margin">
<div class="col-xs-12">
<div class="col-xs-3">
<div id="UploadStatusMessage"></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0%
</div>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="alert alert-default" id="PollingStatusMessage"></div>
</div>
</div>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<%:Scripts.Render("~/Scripts/jQueryForm") %>
</asp:Content>
파일 업로드 컨트롤러 CS
public class FileUploadController : ApiController
{
[HttpPost] //this is demo, lets assume that user is uploading a file and in the same method, some long running operation is happening.
public HttpResponseMessage Upload()
{
var requestId = HttpContext.Current.Request.Form["RequestTracker"];
if (HttpContext.Current.Request.Files.Count > 0)
{
var postedFile = HttpContext.Current.Request.Files[0];
var fileNameParts = postedFile.FileName.Split('\\');
var fileName = fileNameParts[fileNameParts.Length - 1];
fileName = string.Format("{0}_{1}", DateTime.Now.Ticks.ToString(), fileName);
string filePath = Path.Combine("c:\\temp", fileName);
postedFile.SaveAs(filePath);
}
//Note: usually, this will be some other operation (database insert/update, data validation etc)
//Inorder to show the exact status/progress, the backend should store some indication which can be retrieved using another ajax call by polling
ObjectCache cache = MemoryCache.Default;
cache.Remove(requestId);//remove any previous for demo purpose
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddMinutes(10);
List<int> taskStatus = new List<int>();
//long running task 1
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(100);
taskStatus.Add(i);
}
cache.Set(requestId, taskStatus, policy);
//long running task 2
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(100);
taskStatus.Add(i);
}
cache.Set(requestId, taskStatus, policy);
//long running task 3
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(100);
taskStatus.Add(i);
}
cache.Set(requestId, taskStatus, policy);
//long running task 4
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(100);
taskStatus.Add(i);
}
cache.Set(requestId, taskStatus, policy);
return Request.CreateResponse(HttpStatusCode.OK, "All Operations Completed");
}
}
폴링 컨트롤러 CS
public class PollingController : ApiController
{
[HttpPost]
public HttpResponseMessage GetStatus(UploadStatusRequest request)
{
ObjectCache cache = MemoryCache.Default;
var fileUploadStatus = cache.Get(request.RequestId) as List<int>;
var count = 0;
if (fileUploadStatus != null)
{
count = fileUploadStatus.Count;
}
return Request.CreateResponse(HttpStatusCode.OK, "Processed data : " + count + ". Please wait...");
}
}
타이프 스크립트 파일 :
namespace jQueryForm {
export class FileUploadComponent {
progressBar: JQuery = $('.progress-bar');
importFile: JQuery = $('#ImportFile');
uploadStatusMessage: JQuery = $('#UploadStatusMessage');
pollingStatusMessage: JQuery = $('#PollingStatusMessage');
pollingInstance: any = null;
public RegisterEvents() {
var instance: FileUploadComponent = this;
instance.importFile.on('change', function() {
instance.ResetProgressBar();
});
var requestStatusTracker = null;
$('#ImportFileForm').ajaxForm({
beforeSubmit: function (arr, $form, options) {
requestStatusTracker = new Date().getMilliseconds();
arr.push({ name: 'RequestTracker', value: requestStatusTracker });
return true;
},
beforeSend: function (xhr, options) {
instance.ResetProgressBar();
instance.uploadStatusMessage.text('Uploading...');
},
//Note: The uploadProgress method displays the status of file transfer progress to web api method. Once the file is completely transferred to Web API method,
// the percentage will become 100. But, there could be other operations once the file is reached Web API and those are not counted.
uploadProgress: function (event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
instance.progressBar.css("width", percentVal).attr("aria-valuenow", percentComplete).text(percentVal);
if (percentComplete == 100) {
var uploadStatusRequest = new Entities.UploadStatusRequest();
uploadStatusRequest.RequestId = requestStatusTracker;
instance.Poll(uploadStatusRequest);
instance.uploadStatusMessage.text('File Upload Complete.');
}
},
success: function (data) {
//instance.ResetProgressBar();
//Note: all operations completed in the web api method and the success response is received from the controller
clearTimeout(instance.pollingInstance);
instance.pollingStatusMessage.html(data);
},
error: function (xhr) {
},
complete: function (xhr) {//controller has completed all the action
}
});
}
private ResetProgressBar() {
this.progressBar.css("width", '0%').attr("aria-valuenow", 0).text('0%');
this.uploadStatusMessage.empty();
}
private Poll(uploadStatusRequest) {
var instance: FileUploadComponent = this;
instance.pollingInstance = setTimeout(function() {
$.ajax({
url: "api/Polling/GetStatus", data: uploadStatusRequest, dataType: "json", type: 'POST', success: function (data) {
//Update your status
instance.pollingStatusMessage.html(data);
//Setup the next poll recursively
instance.Poll(uploadStatusRequest);
}, error: function (xhr) {
instance.pollingStatusMessage.html(xhr.responseText);
}
});
}, 2000);
}
}
}
$(function() {
var fileUploadComponent = new jQueryForm.FileUploadComponent();
fileUploadComponent.RegisterEvents();
});
출력 :
아래와 같이 진행을 사용자에게 표시되는,

오프로드 새로운 스레드의 처리 및 업데이트는 JavaScript 폴링을하거나 SignalR을 사용 서버에서 클라이언트로 업데이트를 푸시합니다. –
@JasonP, 업데이트를 위해 javascript 폴링에 대한 코드 샘플/참조가 있습니까? –
그냥'setTimeout' 또는'setInterval'을 사용할 것입니다. 다른 옵션이 "영원한 프레임"이라고 가정합니다. https://www.google.com/?q=forever%20frame%20iframe –