2016-07-28 21 views
0

Ich habe den folgenden Code, der eine (normalerweise lokale: 127.0.0.1:8080) XML-Datei abhören und in eine Klasse deserialisieren soll Objekt.Schnellste/geringste ressourcenintensive Möglichkeit zum Deserialisieren von XML aus einer URL bei Verwendung in einer Schleife

private void deserializer() 
    { 
     internal XmlSerializer serializer = new XmlSerializer(typeof(myAPI)); 
     EventWaitHandle MyEventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 
     while (!Global.IsShuttingDown) 
     { 
      MyEventWaitHandle.WaitOne(10); 
      XmlReader reader = XmlReader.Create("http://" + apiAddress + ":" + apiPort + "/api"); 
      apiData = (myAPI)serializer.Deserialize(reader); 
      updateChannelData(); 
     } 
    } 

Dies funktioniert, aber aufgrund der Geschwindigkeit, mit der ich Datenpool kann ein bisschen mehr von einer Belastung für die Maschine als Ich mag würde.

Die API ist in Stein, so dass ich nicht UDP oder COM oder etwas ähnliches, nur XML von einer lokalen URL verwenden kann.

Gibt es einen effektiveren Weg, dies zu tun? Auch die XmlReader hat keine Option, die String-Antwort zu speichern, so dass ich es für Änderungen vergleichen kann, so dass möglicherweise updateChannelData() überspringen, wenn keine Änderungen erkannt werden, was kann ich tun, ist leicht, diese Implementierung hinzuzufügen?

+0

@ChibuezeOpata 'XmlSerializer', wird Code modifizieren, um sie definiert ist. – Wobbles

+0

Haben Sie versucht [Protobuf] (http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/)? –

+0

@ChibuezeOpata "Die API ist fest in Stein, so dass ich nicht UDP oder COM oder etwas ähnliches, nur XML von einer lokalen URL verwenden kann." – Wobbles

Antwort

0

weiter zu erklären, müssen Sie

  1. Ihren XML-Datei Inhalt herunterladen und auf Klassenebene oder mehr globale Ebene
  2. Jedes Mal, wenn Sie XML-Datei herunterladen, vergleichen mit dem gespeicherten man vor speichern Verfahren deserialisieren (Sie sollten dies nicht tun müssen, wenn Sie den Vergleich nur, wenn sie sich geändert hat) ein
  3. Verwenden schneller/effizienter Deserializer, so dass Sie verschwenden müssen nicht Ihren Raum

Hinweis: Für eine höhere Leistung/oder wenn Ihre XML-Datei groß ist, sollten Sie nur den Header lesen, um zu sehen, ob sich die content length geändert hat, bevor Sie mit dem Download fortfahren.

Eine tatsächliche Implementierung kann wie folgt aussehen:

private int currentXmlLength; 

private void deserializer() 
{ 
    internal XmlSerializer serializer = new XmlSerializer(typeof(myAPI)); 
    EventWaitHandle MyEventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 
    while (!Global.IsShuttingDown) 
    { 
     MyEventWaitHandle.WaitOne(10); 
     string myUrl = "http://" + apiAddress + ":" + apiPort + "/api"; 
     int len = GetContentLength(myUrl); 
     if(len > 0 && len != currentXmlLength) 
     { 
      XmlReader reader = XmlReader.Create(myUrl); 
      //you may consider using https://github.com/tomba/netserializer here 
      apiData = (myAPI)serializer.Deserialize(reader); 
      updateChannelData(); 
     } 
    } 
} 

private int GetContentLength(string url) 
{ 
    int ContentLength = -1; 
    System.Net.WebRequest req = System.Net.HttpWebRequest.Create(url); 
    req.Method = "HEAD"; 
    using (System.Net.WebResponse resp = req.GetResponse()) 
    { 
     int.TryParse(resp.Headers.Get("Content-Length"), out ContentLength));    
    } 
    return ContentLength; 
}