1

我有一個MVC4應用程序有一個或兩個長時間運行的請求。爲此,首先,迭代我將把它們作爲同步任務。但是,我會像從這些任務跟蹤輸出顯示在我的Web應用程序的可選「進度」窗口中。我應該如何製作一個自定義的Trace:用於在網頁上顯示跟蹤信息的Listener?

我看到兩個候選解決方案,涉及一個數據庫跟蹤偵聽器或一個跟蹤偵聽器,該偵聽器擁有存儲在會話中的「跟蹤集合」對象的權限。然後,「進度」窗口可以使用setInterval和Ajax調用定期輪詢這些跟蹤存儲。

這聽起來太簡單了,這就是爲什麼我問我該怎麼做。是否有更好的方法,既定的模式和技巧,還是它的價值不大?

回答

1

您可以使用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"); 
} 
+0

所以我會寫一個'SignalRTraceListener'?有趣。 – ProfK

+0

我已經添加了一些示例代碼,使用NuGet的最新版本的SignalR(它已經在文章中使用過一點)。然後,您可以將服務器端代碼調整爲SignalRTraceListener。 –

相關問題