Недостаточно памяти после публикации на сервере - PullRequest
0 голосов
/ 16 декабря 2011

Q:

После публикации приложения в IIS я сталкиваюсь со следующей проблемой:

иногда приложение зависает, затем, когда я пытаюсь обновить, я получаю resource not found.

Я проверяю свою папку с ошибками: и я нахожу более одной ссылки на следующее исключение

Out of Memory Exception.

Я читаю данные из файла xml и разделяю их для последующего добавления в эквивалентные таблицы базы данных.

Я получаю данные из xml через LINQ:

Как это:

XDocument xmlDoc = XDocument.Load("c:\\test.xml");
            var q = from c in xmlDoc.Descendants("User")
                    select (string)c.Attribute("FirstName") + "■" + (string)c.Attribute("LastName")+ "■" + (string)c.Attribute("age");


foreach (string name in q)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        string substring = name.Split('■')[i];
                    }
                }

Примечания:

  • Количество записей в каждом узле q может достигать 2000 записей.
  • Количество полей, разделенных максимум около 7 (для каждого запись)
  • У меня есть около десяти сущностей (я имею в виду около десяти q, которые я обрабатываю).

Пожалуйста, Как быстро изменить мой код, чтобы решить эту фатальную проблему, особенно это происходит с одним пользователем, что если более одного пользователя, скажем, 100 пользователей параллельно !!!

Ответы [ 2 ]

2 голосов
/ 16 декабря 2011

Если вы обнаружите, что использование XDocument дорого в памяти (и из вашего описания может показаться, что вы могли бы быть, хотя проблема может быть в другом месте), тогда это вполне может стоить заменив его использование читателем только для пересылки, который не хранит связанные списки дочерних узлов:

private struct UserNode
{
  public string FirstName{get;private set;}
  public string LastName{get;private set;}
  public int Age{get;private set;}
  public UserNode(string firstName, string lastName, int age)
  {
    FirstName = firstName;
    LastName = lastName;
    Age = age;
  }
}

private static IEnumerable<UserNode> ReadUserNodes(string filePath)
{
  using(FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
  using(XmlReader xrdr = new XmlTextReader(fs))
    while(xrdr.Read())
      if(xrdr.NodeType == XmlNodeType.Element && xrdr.LocalName == "User")
        yield return new UserNode(xrdr.GetAttribute("FirstName"), xrdr.GetAttribute("LastName"), int.Parse(xrdr.GetAttribute("age")));
}

/*...*/

foreach(UserNode user in ReadUserNodes(@"c:\test.xml"))
{
  //Do something useful with users...
}

Невозможно с этим сделать что-то вроде проверки свойства Parent или PreviousNode для данного элемента, но вы все равно этого не делаете, так кого это волнует? Поскольку данные, необходимые для проверки таких свойств, не сохраняются в памяти, использование памяти намного меньше.

1 голос
/ 16 декабря 2011

Я не знаю, решит ли это все проблемы с памятью, но вам не следует объединять строки, а затем сразу их разбивать.Вместо этого вы должны использовать анонимный объект для запроса:

XDocument xmlDoc = XDocument.Load("c:\\test.xml");
var q = from c in xmlDoc.Descendants("User")
        select new
        {
            FirstName = (string)c.Attribute("FirstName"),
            LastName = (string)c.Attribute("LastName"),
            Age = (string)c.Attribute("age")
        };

foreach (var user in q)
{
    // This just shows how to access the properties.
    // You can do whatever else you want with them at this point
    Console.WriteLine(user.FirstName);
    Console.WriteLine(user.LastName);
    Console.WriteLine(user.Age);
}

Конкатенация строк и разбиение строк являются относительно дорогими операциями, так как загрузка большого XML-документа в память.Выполнение всего вместе может способствовать возникновению проблемы, с которой вы сталкиваетесь, хотя из этого контекста действительно трудно понять.

...