您可以使用SignalR將來自服務器端的跟蹤消息直接發送到瀏覽器中的「進度窗口」。
Dino Esposito在msdn上寫了一個article,它和進度條做類似的事情。
這樣您就不需要從進度窗口輪詢服務器,也不需要使用Session來存儲輪詢請求之間的消息。
編輯:樣品添加
SignalR已經改變了一點,因爲這文章寫。除了登記在Global.asax中的路由,在視圖中包括腳本,你需要以下一段JavaScript代碼初始化客戶端signalR代理,並增加了一個函數來顯示進度信息:
<script type="text/javascript">
$(document).ready(function() {
// Create a proxy for the server endpoint
var progressHub = $.connection.progressHub;
$.connection.hub.start();
// Add a client-side callback to process any data
// received from the server
progressHub.client.addProgress = function (message) {
$('#progress').append('<li>' + message + '</li>');
};
});
</script>
讓我們假設您在該頁面上有一個按鈕,可以觸發服務器中長時間運行的進程。爲了簡單起見,我將在家庭控制器中使用以下jQuery調用名爲RunProcess
的方法。這樣服務器就知道誰需要接收進度數據將通過SignalR客戶端的ID:
$("#runProcess").click(function() {
var id = $.connection.hub.id;
$.get("/Home/RunProcess/" + id);
});
在服務器端,HomeController的下列方法將模擬長時間運行的過程。爲了使用SignalR通知客戶端,您需要使用GlobalHost.ConnectionManager.GetHubContext<T>()
來獲取上下文。然後,它需要調用已在客戶端代理定義的方法addProgress(message)
,只是客戶端與接收到的ID:
public void RunProcess(string id)
{
var progressHub = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
progressHub.Clients.Client(id).addProgress("25% completed");
Thread.Sleep(2000);
progressHub.Clients.Client(id).addProgress("50% completed");
Thread.Sleep(3000);
progressHub.Clients.Client(id).addProgress("75% completed");
Thread.Sleep(2000);
progressHub.Clients.Client(id).addProgress("Process Finished");
}
所以我會寫一個'SignalRTraceListener'?有趣。 – ProfK
我已經添加了一些示例代碼,使用NuGet的最新版本的SignalR(它已經在文章中使用過一點)。然後,您可以將服務器端代碼調整爲SignalRTraceListener。 –