Comment surmonter OutOfMemoryException en extrayant de gros documents XML à partir d’une API?

Je tire 1M + enregistrements d’une API. L’opération fonctionne correctement, mais je reçois une exception de mémoire ReadToEnd lorsque ReadToEnd tente de ReadToEnd dans une variable chaîne.

Voici le code:

  XDocument xmlDoc = new XDocument(); HttpWebRequest client = (HttpWebRequest)WebRequest.Create(uri); client.Timeout = 2100000;//35 minutes WebResponse apiResponse = client.GetResponse(); Stream receivedStream = apiResponse.GetResponseStream(); StreamReader reader = new StreamReader(receivedStream); ssortingng s = reader.ReadToEnd(); 

Trace de la stack:

 at System.Text.SsortingngBuilder.ToSsortingng() at System.IO.StreamReader.ReadToEnd() at MyApplication.DataBuilder.getDataFromAPICall(Ssortingng uri) in c:\Users\RDESLONDE\Documents\Projects\MyApplication\MyApplication\DataBuilder.cs:line 578 at MyApplication.DataBuilder.GetDataFromAPIAsXDoc(Ssortingng uri) in c:\Users\RDESLONDE\Documents\Projects\MyApplication\MyApplication\DataBuilder.cs:line 543 

Que puis-je faire pour contourner ce problème?

Il semble que votre fichier soit trop volumineux pour votre environnement. Le chargement du DOM pour un fichier volumineux peut être problématique, en particulier lors de l’utilisation de la plate-forme win32 (vous n’avez pas indiqué si c’était le cas).

Vous pouvez associer la vitesse et l’efficacité de la mémoire de XmlReader à la commodité de XElement / Xnode, etc., et utiliser un XStreamingElement pour enregistrer le contenu transformé après le traitement. C’est beaucoup plus efficace en mémoire pour les gros fichiers

Voici un exemple en pseudo-code:

  // use a XStreamingElement for writing var st = new XStreamingElement("root"); using(var xr = new XmlTextReader(stream)) { while (xr.Read()) { // whatever you're interestd in if (xr.NodeType == XmlNodeType.Element) { var node = XNode.ReadFrom(xr) as XElement; if (node != null) { ProcessNode(node); st.Add(node); } } } } st.Save(outstream); // or st.WriteTo(xmlwriter); 

XMLReader est la voie à suivre lorsque la mémoire pose un problème. C’est aussi le plus rapide.

Malheureusement, vous n’avez pas montré votre code, mais il semble que tout le fichier est en cours de chargement en mémoire. C’est ce que vous devez éviter.

Il est préférable d’utiliser un stream pour traiter le fichier sans tout charger en mémoire.