Подтвердить что ты не робот

System.OutOfMemoryException: Исключение типа "System.OutOfMemoryException" было выбрано в angularjs

Я потратил пару недель на эту проблему. но все же я не могу решить эту проблему.

Я вызываю службу веб-API с помощью http в angularjs

           $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) {
               }
           })

Я поставил точку останова в кодировании сервера и клиента.

Когда я вызываю службу, метод на стороне сервера быстро удаляется

Мой метод на стороне сервера (am Использование MVC WEB API с инфраструктурой сущностей)

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

Я проверил, служба возвращает 8 записей (8 строк из базы данных) с точкой останова в objIProjectService.ListOfProject(); этой строке.

все идет хорошо. Но мои (ответные) http.success and http.error функции обратного вызова работают очень медленно.

Пожалуйста, смотрите ниже изображение для производительности, когда я вызываю методы http

enter image description here

Наконец, http error function ударит через 5 или 10 минут с этим ниже сообщением об ошибке.

System.OutOfMemoryException: было исключено исключение типа 'System.OutOfMemoryException'

Это проблема. Пожалуйста, дайте мне знать, как я могу это решить?

На самом деле я сделал что-то для этой проблемы.

  • Я очистил временную папку - не работает
  • Я перезапустил Visual Studio и очистил решение, перезапустил мою систему и восстановил визуальную студию. - не работает.
  • Но если я удалил несколько строк в базе данных (использую sql server 2008 r2), тогда он работает.

Например, если моя таблица базы данных имеет менее 7 строк, то она быстро работает без этой ошибки. Но если моя таблица имеет более 8 строк, то она работает очень медленно и бросает ошибку?? Почему?? ре не могли бы вы поделиться своим решением, если вы столкнулись с этой проблемой.

4b9b3361

Ответ 1

Я думаю, что проблема заключается в том, что сериализатор получает доступ ко всем связанным свойствам вашего класса проекта, поэтому вместо прямого возврата класса Entity Framework создайте новый класс для представления данных, которые вы хотите отправить через ваш 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()...

Ответ 2

Откройте Sql Server Profiller и просмотрите созданные SQL-запросы и результаты. А затем попробуйте выполнить в sql-окне эти необработанные запросы. Вероятно, вы поймете после этого.

Ответ 3

Проблема в том, что сериализация информации занимает много времени. Вы получаете доступ ко всем связанным классам вашего класса проекта, что может привести к значительному ущербу при работе с аспектами памяти.

вы можете разрешить это двумя способами:

Один из них - вернуть ваш promises и затем извлечь данные:

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

Второй вариант будет в коде, используя фреймворк Entity или запросы linq.

Используйте запросы выбора, чтобы снизить нагрузку на стороне сервера и на стороне клиента следующим образом:

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

таким образом вы сможете снизить нагрузку на сериализацию данных и, возможно, избежать outOfMemoryExcexption.

Нет необходимости открывать Sql Profiler здесь, так как данные со стороны сервера поступают в разумные сроки.

Ответ 4

Спецификация HTTP не налагает ограничение по размеру для сообщений. Проблема с запросами GET заключается в том, что параметры встроены в URL-адрес, который ограничен по размеру (этот лимит зависит от браузера и сервера). Не используйте запрос GET для больших данных, используя POST.

есть еще одна тема. Если вы используете MVC и работаете над большими данными, вам нужно использовать этот.

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

или

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

from: MSDN

Я надеюсь, что это решит вашу проблему.

Ответ 5

Продолжая предложение Криса Варнса и описывая возможную причину.

Позвольте мне угадать... вы используете инфраструктуру сущности с включенной ленивой загрузкой. Поэтому во время сериализации каждое навигационное свойство, которое у вас есть, иногда загружается данными и рекурсивно. Например: Project содержит Worker, который содержит ссылку на тот же Project в некоторых навигационных свойствах, таких как WorkerProjects.

Сериализатор пытается понять это, но он не может, без какого-либо намека. самый простой способ проверить, что происходит, - отключить ленивую загрузку сущности и получить эту точку останова сразу после ToList() и непосредственно перед return.

BTW. Сериализация такой структуры для JSON - это нечто вроде невозможного. У вас должен быть внешний механизм (например, cycle.js использует XPath для кодирования такой ссылки) для обработки дублированных ссылок и циклов.