2015-05-02 88 views
19

我已經花了幾個星期的時間來解決這個問題。但仍然無法解決此問題。System.OutOfMemoryException:類型'System.OutOfMemoryException'的異常被拋出angularjs

我正在使用httpangularjs

  $http({ 
       method: 'GET', 
       url: rootUrl + '/api/Project/ProjectList', 
       headers: { 
        'Content-Type': "application/json; charset=utf-8" 
       } 
      }).success(function (response) { 
       $scope.ProjectList = response; 
      }).error(function (response, errorCode) { 
       if (errorCode == 444) { 
       } 
      }) 

調用Web API服務,我已經把破發點中的服務器和客戶端的編碼。

當我打電話的服務,服務器端的方法快速

我的服務器端方法(正在使用的MVC Web API與實體框架

[ActionName("ProjectList")] 
    [HttpGet] 
    public IList<Project> ProjectList(Project projectModel) 
    { 
     return objIProjectService.ListOfProject(); 
    } 

我查了一下,在服務回報8記錄(來自數據庫的8行),在此行中有一箇中斷點objIProjectService.ListOfProject();

一切都很順利。但我的(回覆)回調函數速度非常慢。

請參考下面的圖像的性能,同時我調用http方法

enter image description here

最後http error function命中後5或10分鐘用下面這樣的錯誤消息。

的System.OutOfMemoryException:類型的異常 '的System.OutOfMemoryException' 被拋出

這就是問題所在。請讓我知道我該如何解決它?

其實我爲這個問題做了些什麼。

  • 我已清除臨時文件夾 - 不工作
  • 我必須重新啓動Visual Studio和清潔解決方案,重新啓動我的系統和修復視覺studio.-不工作
  • 但如果我已刪除了一些行在數據庫(正在使用sql server 2008 r2),那麼它的工作。

例如,如果我的數據庫表的行數低於7行,那麼它的運行速度很快,沒有出現錯誤。 但是,如果我的表有超過8行,那麼它的工作非常緩慢,並拋出錯誤? 爲什麼? re 如果您遇到此問題,請分享您的解決方案。

+1

您需要發佈'objIProjectService.ListOfProject();'函數的實現,數據庫表的結構和示例數據,它在哪裏可以正常工作,並且它會給出錯誤信息 –

+0

該代碼是:'return context .products.ToList()' –

+0

嘗試使用JSON作爲返回類型,將對象序列化並將其發回 – Munzer

回答

11

我認爲問題在於serialiser正在訪問項目Class上的所有相關屬性,因此不是直接返回實體框架類,而是創建一個新類來表示您希望通過api發送的數據(進一步研究DTO類以獲取更多信息)

您可以使用Select Linq方法來獲取您的新dto類的列表,該列表中填充了來自EF調用的數據。

var projects = objIProjectService.ListOfProject(); 

return projects.Select(p => new ProjectDTO() { 
    ID = p.Id 
    //... other properties of DTO class 
}).ToList(); 

甚至更​​好,如果你把這個選擇方法,爲您的EF查詢(即context.projects.Select(/* select info here */).ToList(),你可以確保EF只帶回你建立一個API時需要

經常檢查領域json/XML響應,確保序列化的數據包含你期望它產生的東西,對於實體框架,當響應瀏覽所有相關的表時,這個響應可能會變得非常巨大,從而拉出所有鏈接的信息,然後嘗試對其進行序列化。

作爲個人偏好我總是喜歡返回IHttpActionResult它允許你管理什麼被髮送回客戶端,特別是當有問題時,控制器有多種方法可以用來創建這個例如OK(), BadRequest(), InternalServerError() ...

+0

感謝您的解釋。 –

2

打開Sql Server Profiller並觀察EF生成的sql查詢和結果。然後嘗試在SQL窗口上執行這些原始查詢。在此之後大概你會明白。

0

這裏的問題是信息的序列化需要很長時間。您正在訪問項目類的所有相關類,這可能會在處理內存方面時導致嚴重損壞。

您可以通過兩種方式解決此問題:

一個是回到你的承諾,然後獲取數據:

return $http({ 
       method: 'GET', 
       url: rootUrl + '/api/Project/ProjectList', 
       headers: { 
        'Content-Type': "application/json; charset=utf-8" 
       } 
      }).then(function (response) { 

第二個選項將在代碼中,使用實體框架或LINQ查詢。

使用SELECT查詢,以降低在服務器端和客戶端的負擔如下:您將能夠降低數據序列化的負擔

var projectsQuery = from p in ProjectModel as pm where pm.Id = p.Id select p.SomeValue 
return projectsQuery 

這種方式有可能會避免outOfMemoryExcexption。

由於來自服務器端的數據在合理的時間到來,因此無需在此處打開Sql Profiler。

0

HTTP規範不會對帖子強加特定的大小限制。 GET查詢的問題在於參數嵌入在URL中,該URL的大小有限(此限制取決於瀏覽器和服務器)。 不要對大數據使用GET查詢使用POST。

還有另外一個話題如果你使用的是MVC,而你在處理大數據,那麼你需要使用這個。

<appSettings> 
    <add key="aspnet:MaxJsonDeserializerMembers" value="150000" /> 
</appSettings> 

<system.webServer> 
<security> 
    <requestFiltering> 
     <requestLimits maxAllowedContentLength="1000000" /> 
    </requestFiltering> 
</security> 

來自:MSDN

我希望這將解決你的問題。

0

進一步與Chris Warnes的建議和描述可能的原因。

讓我猜...你使用啓用延遲加載的實體框架。因此,在序列化過程中,您所擁有的每個導航屬性都會延遲並遞歸地加載數據。例如:Project包含Worker,其中在某些導航屬性(例如WorkerProjects)中包含對相同Project的引用。

序列化程序試圖理解它,但它不能,沒有一些提示。 檢查發生了什麼的最簡單方法是禁用實體框架延遲加載並在ToList()之後並在return之前獲得該斷點。

順便說一句。將這種結構序列化爲JSON是 - 種 - 不可能的。您需要有外部機制(如cycle.js使用XPath來編碼這樣的引用)來處理重複的引用和循環。

相關問題