В основном у меня есть программа, которая при запуске загружает список файлов (как FileInfo
) и для каждого файла в списке загружает XML-документ (как XDocument
).
Затем программа считывает данные из него в контейнерный класс (сохраняя как IEnumerables
), после чего XDocument
выходит за пределы области.
Программа затем экспортирует данные из класса контейнера в базу данных. После экспорта контейнерный класс выходит из области видимости, однако сборщик мусора не очищает контейнерный класс, который, поскольку его сохранение как IEnumerable
, похоже, приводит к XDocument
остается в памяти (не уверен, является ли это причиной, но диспетчер задач показывает, что память из XDocument
не освобождается).
Поскольку программа перебирает несколько файлов в цикле, в конечном итоге программа выдает исключение нехватки памяти. Чтобы смягчить этот эффект, я использовал
System.GC.Collect();
для принудительного запуска сборщика мусора после того, как контейнер выходит за пределы области видимости. это работает, но мои вопросы:
XDocument
удаляется? Спасибо.
Изменить: Примеры кода:
Класс контейнера:
общедоступный IEnumerable CustomClassOne {get; установлен; }
- Верно ли это? (Принуждение к запуску сборщика мусора кажется немного странным)
- Есть ли лучший способ убедиться, что память
XDocument
удаляется?
- Может быть другая причина, кроме IEnumerable , что память документа не освобождается?
Спасибо.
Изменить: Примеры кода:
Класс контейнера:
общедоступный IEnumerable CustomClassOne {get; установлен; }
- Верно ли это? (Принуждение к запуску сборщика мусора кажется немного странным)
- Есть ли лучший способ убедиться, что память
XDocument
удаляется?
- Может быть другая причина, кроме IEnumerable , что память документа не освобождается?
Спасибо.
Изменить: Примеры кода:
Класс контейнера:
общедоступный IEnumerable CustomClassOne {get; установлен; }
общедоступный IEnumerable CustomClassTwo {получить; установлен; }
общедоступный IEnumerable CustomClassThree {получить; установлен; }
...
общедоступный IEnumerable CustomClassNine {получить; установлен; }
Пользовательский класс:
public long VariableOne {get; установлен; }
public int VariableTwo {получить; установлен; }
общедоступные DateTime VariableThree {получить; установлен; }
...
Во всяком случае, это действительно основные структуры. Пользовательские классы заполняются через класс контейнера из XML-документа. Сами заполненные структуры используют очень мало памяти.
Контейнерный класс заполняется из одного XML-документа, выходит за пределы области видимости, затем загружается следующий документ, например,
public static void ExportAll(IEnumerable<FileInfo> files)
{
foreach (FileInfo file in files)
{
ExportFile(file);
//Temporary to clear memory
System.GC.Collect();
}
}
private static void ExportFile(FileInfo file)
{
ContainerClass containerClass = Reader.ReadXMLDocument(file);
ExportContainerClass(containerClass);
//Export simply dumps the data from the container class into a database
//Container Class (and any passed container classes) goes out of scope at end of export
}
public static ContainerClass ReadXMLDocument(FileInfo fileToRead)
{
XDocument document = GetXDocument(fileToRead);
var containerClass = new ContainerClass();
//ForEach customClass in containerClass
//Read all data for customClass from XDocument
return containerClass;
}
Забыл упомянуть этот бит (не уверен, соответствует ли он), файлы могут быть сжаты как .gz, поэтому у меня есть метод GetXDocument ()
для его загрузки
private static XDocument GetXDocument(FileInfo fileToRead)
{
XDocument document;
using (FileStream fileStream = new FileStream(fileToRead.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
if (String.Equals(fileToRead.Extension, ".gz", StringComparison.OrdinalIgnoreCase))
{
using (GZipStream zipStream = new GZipStream(fileStream, CompressionMode.Decompress))
{
document = XDocument.Load(zipStream);
}
}
else
{
document = XDocument.Load(fileStream);
}
return document;
}
}
Надеюсь, этой информации достаточно.
Спасибо
Редактировать: System.GC.Collect ()
не работает 100% времени, иногда кажется, что программа сохраняет XDocument
, у кого-то есть идея, почему это может быть?
public static ContainerClass ReadXMLDocument(FileInfo fileToRead)
{
XDocument document = GetXDocument(fileToRead);
var containerClass = new ContainerClass();
//ForEach customClass in containerClass
//Read all data for customClass from XDocument
containerClass.CustomClassOne = document.Descendants(ElementName)
.DescendantsAndSelf(ElementChildName)
.Select(a => ExtractDetails(a));
return containerClass;
}
private static CustomClassOne ExtractDetails(XElement itemElement)
{
var customClassOne = new CustomClassOne();
customClassOne.VariableOne = Int64.Parse(itemElement.Attribute("id").Value.Substring(4));
customClassOne.VariableTwo = int.Parse(itemElement.Element(osgb + "version").Value);
customClassOne.VariableThree = DateTime.ParseExact(itemElement.Element(osgb + "versionDate").Value,
"yyyy-MM-dd", CultureInfo.InvariantCulture);
return customClassOne;
}