2014-04-23 41 views
1

在我的應用程序中,我通過上傳XML文件開始導入過程。上傳完成後,將運行一系列存儲過程並解析xml文件,並將數據插入許多不同的表中。隨着進展,將更新Stats表以顯示插入的進度。表格有4列:BatchId,BatchCount,ProcessCountErrorCountBatchCount是所有記錄的計數。如果記錄插入正確沒有問題ProcessCount增加1,如果失敗ErrorCount增加1.(這兩列在導入過程中總是變化)SignalR輪詢並不總是返回準確的數據庫結果

我的主要目標是顯示導入進度使用SignalR 。我有一箇中心輪詢方法,因爲我在用戶界面中看到更新的時間戳。然而,問題在於計數值總是爲0(初始值),或者非常偶爾會讀取一次,並顯示一些像985這樣的隨機數。如果它讀取了一個值,它只會執行一次,而不會再次更改。這裏是我的樞紐方法:

public void BeginPolling() 
{ 
    while (true) 
    { 
     var stats = _repository.GetImportStats(); 
     var message = "Preparing file..."; 

     if (stats != null) 
     { 
      message = DateTime.Now + " - Count: " + stats.ProcessCount.ToString(); 
     } 
     else 
     { 
      message = DateTime.Now + " - Stats result returned null."; 
     } 

     //the message displays in a div on my UI 
     Clients.Caller.showProgress(message); 

     //I have tried various sleep times (1000, 5000, 10000) 
     Thread.Sleep(5000); 
    } 
} 

下面是我的_repository.GetImportStats方法,用於測試目的,只是抓住一個(也是唯一)記錄:

public Stats GetImportStats() 
{ 
    return DataContext.Stats.FirstOrDefault(); 
} 

同樣的測試,我試圖只是把一個按鈕在我的用戶界面,使ajax調用相同的GetImportStats()方法,它總是返回ProcessCount就好,所以我認爲問題在於我的SignalR實現。任何幫助表示讚賞!

回答

2

你正在做一個實體框架的大佬,你有一個長壽的DbContext。你永遠不應該這樣做。

在這種情況下,您遇到了Entity Framework的變更跟蹤器的問題。默認情況下,EF使用MergeOption.AppendOnly

這意味着默認情況下,對於每個EF查詢,EF將只將行反序列化爲對象,IFF鍵與上下文的Change Tracker中的對象不匹配。

因此,如果每個循環都使用EF上下文的相同實例,則EF每次執行查詢時都會使用緩存的值(SQL運行,但EF不會像您期望的那樣創建或更改對象) 。如果你堅持EF上下文短的規則,這是完全可以預料的。

要解決這個問題,您有幾個選擇。

  • 實例化一個新的EF上下文(和更改跟蹤器)每個循環。
  • 告訴EF在每個查詢上使用MergeOption.OverwriteChanges
  • 告知EF不要使用變更追蹤器AT ALL(這會禁用寫入訪問,但速度會更快)。
+0

標記爲解決眼前的問題的答案,但也提供了有關halter73答案的有用建議。 – Goose

3

對此可能最好使用GetHubContextTimer

我在BeginPolling看到的一個潛在問題是它永遠不會返回。對於除WebSockets以外的所有SignalR傳輸,這意味着將有一個永不結束每次調用BeginPolling時都會啓動XHR。

這不但不必要地浪費了服務器資源,它還可能會干擾客戶自browsers limit the number of simultaneous connections that can be made to a single server以來接收更多消息的能力。


P.S.製作BeginPollingasync和使用await Task.Delay(...);可以防止你不必要地堅持服務器線程與Thread.Sleep,但這並不能解決你永無止境的XHR問題。因此,我再次建議在Hub外部使用GetHubContextTimer

+0

感謝您的建議,我已經開始實施這些更改。 – Goose