0

I have the following code which is designed to listen to a (usually local: 127.0.0.1:8080) xml file and deserialize it into a class object.

    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();
        }
    }

This works, but due to the rate at which I pool data, can be a bit more of a burden on the machine than I would like.

The API is fixed in stone so I cannot use UDP or COM or anything like that, only XML from a local URL.

Is there a more effective way to do this? Also the XmlReader has no option to store the string response so I can compare it for changes thus possibly skipping updateChannelData() if there are no changed detected, what can I do that is lightweight to add this implementation?

Wobbles
  • 3,033
  • 1
  • 25
  • 51
  • @ChibuezeOpata `XmlSerializer`, will modify code so it is defined. – Wobbles Jul 28 '16 at 14:04
  • Have you tried [Protobuf](http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/) ? – Chibueze Opata Jul 28 '16 at 14:04
  • @ChibuezeOpata "The API is fixed in stone so I cannot use UDP or COM or anything like that, only XML from a local URL." – Wobbles Jul 28 '16 at 14:07
  • Apparently there are already a lot of [answers on this](http://stackoverflow.com/q/4143421/612717) In essence, you will have to optimize the XmlSerializer class to not bother with parts you don't want or deal specifically with your type. For the second part of your question, you should consider downloading the data using HttpClient or Webclient first before using the reader. – Chibueze Opata Jul 28 '16 at 14:08
  • @ChibuezeOpata That isn't really on topic, it answers the fastest way to (de)serialize net objects, but doesn't focus on what I am forced to use which is XML. – Wobbles Jul 28 '16 at 14:10
  • Is myApi not a dot net object? Can you also post info on that. – Chibueze Opata Jul 28 '16 at 14:12
  • @ChibuezeOpata it is, but I absolutely **must** populate it from URL using XML. Its not a matter of just looking for a fast way to (de)serialize. – Wobbles Jul 28 '16 at 14:13

1 Answers1

0

To explain further, you need to

  1. Download your xml file contents and save at the class level or more global level
  2. Each time you download xml file, compare with the saved one before proceeding to deserialize (you shouldn't need to do this if you're just comparing if it has changed)
  3. Use a faster/more efficient deserializer so you don't have to waste your space

Note: For higher performance/or if your XML file is large then you should consider reading only the header to see if the content length has changed, before actually proceeding with download.

An actual implementation may look like:

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;
}
Community
  • 1
  • 1
Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65