2012-10-25 64 views
0

我有一個長時間的運行操作,您可能會在我的另一個問題(這裏您的參考是firstsecond)中讀到。在一個控制器方法中運行異步操作,並在另一個控制器方法中獲取該操作的結果

在整個交易開始時,項目公開了一個表單,用戶應該在其中指定關於XML文件的所有必要信息並上傳XML文件本身。在該方法中,所有用戶輸入數據都被捕獲並轉到處理文件之王的WCF服務。控制器只獲得了這種處理的任務ID。 然後用戶被重定向到進度條頁面並定期檢索任務完整性的狀態,刷新進度條。

所以這裏是我的問題來了。如果結束處理XML文件,如何獲取結果並將結果顯示給用戶?

我知道HTTP是無狀態協議,但有cookie機制可以幫助在這種情況下。當然,我可能會將處理結果保存到某個臨時位置,例如WCF服務器中的靜態類,但服務的負載很高,因此它會佔用所有提供的內存。

換句話說,我想將任務傳遞給WCF服務(使用netNamedPipeBinding)並儘可能快地接收結果。我想將臨時保存結果轉移到某個緩衝區,並等待客戶端將其收回。


至於我走的是使用不服務的一面,但在客戶端的臨時緩衝區:

using (XmlProcessingServiceClient client = new XmlProcessingServiceClient()) 
{ 
    client.AnalyzeXmlAsync(new Task { fileName = filePath, id = tid }); 
    client.AnalyzeXmlCompleted += (sender, e) => 
    { 
     System.Web.HttpContext.Current.Application.Lock(); 
     // here is I just use single place for all clients. I know it is not right, it is just for illustrating purposes. 
     System.Web.HttpContext.Current.Application["Result"] = e; 
     System.Web.HttpContext.Current.Application.UnLock(); 
    }; 
} 
+0

你有沒有考慮過使用[SignalR](http://signalr.net/) – Jupaol

回答

0

說實話,我並沒有真正得到有關的WCF服務器之類的東西的一部分,但我想我可以給你更多的抽象答案。可以肯定的:

  1. 你有一些字段的表單+文件上傳
  2. 用戶填寫表單並提供一個XML文件
  3. 您發送XML文件到procress它
  4. 的WFC服務
  5. 顯示的平均時間,其更新
  6. 完成後進度條顯示的結果

如果這不是要你想要或者這不是什麼你的問題是關於你可以跳過我的答案,否則繼續閱讀。

在我們開始之前:第3步有點含糊不清:這可能意味着我們將數據發送到服務並等待它返回結果或我們將數據發送到服務,我們不等待它返回結果。

情況1:

  1. 與所有必填字段
  2. 創建您的控制器,它處理回發的操作創建一個視圖的形式。
  3. 該動作會將數據發送到服務,並且當服務返回結果時,您的動作將呈現結果的視圖。
  4. 在提交按鈕上單擊事件添加一個JavaScript。這將觸發對某些服務器端代碼的ajax調用,這將返回進度。
  5. JavaScript的顯示出來的某種正確的進度條和重複每x秒
  6. 本身當控制器完成,它會顯示結果

情況2:

  1. -
  2. -
  3. 將數據發送到服務後,控制器顯示包含進度欄的視圖。
  4. 我們在文檔準備就緒上添加一個javascript事件,它檢查xml文件的狀態並更新進度條。 (相同的情況步驟4中的onclick事件1)
  5. 當進度條達到100%它會重定向到一個不同的網頁,其中顯示了結果

這是否回答你的問題?

最好的問候,

BHD

0

netNamedPipeBinding不會跨機器的通信工作,如果這是你的想法。

如果您想在IIS上託管我們的服務,那麼您將需要使用HTTP作爲其傳輸協議的綁定之一。看看允許兩個端點發送消息的duplex services。這樣服務器可以隨時向客戶端發送消息。您可以爲進度報告創建一個回調界面。如果任務需要花費相當長的時間才能完成,那麼通過HTTP進行報告的開銷可能就沒有問題。

如果您想要通過HTTP與Silverlight進行雙工通信(PollingDuplexHttpBinding),還可以查看Building and Accessing Duplex Services

最後,您可以查找適用於ASP.NET的Comet實現。在CodeProject中,您至少會有一對(CometAsyncPokeIn)。

0

我不確定這是否是最好的解決方案,但我能夠做類似的事情。這是一般設置:

  1. 控制器A初始化一個新類的參數要執行的動作,並通過用戶的會話對象
  2. 新類稱爲在後臺線程的方法有哪些更新的用戶會話,因爲它的進展
  3. 控制器B有json方法,當客戶端JavaScript調用時,檢查用戶的會話數據並返回最新進度。

thread指出,以這樣的方式使用會話對象是壞的,但我敢肯定,你可以用像SQL線程安全的存儲方法或臨時文件類似的東西。

3

我建議您使用SignalR hub來解決您的問題。您可以直接調用客戶端上的方法來通知已完成的操作。這種情況發生時無需處理實施此類戰略時出現的實際基礎設施問題。加上SignalR可以很容易地插入到asp.net MVC應用程序中。

相關問題