在循环中使用时,从URL反序列化XML的最快/资源最少的方法

时间:2016-07-28 14:00:00

标签: c# xml deserialization

我有以下代码,用于侦听(通常是本地:127.0.0.1:8080)xml文件并将其反序列化为类对象。

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

这样可行,但是由于我汇总数据的速度,可能会比我想要的更多的机器负担。

API是固定不变的,所以我不能使用UDP或COM或类似的东西,只能使用本地URL的XML。

有更有效的方法吗?此外,XmlReader没有选项来存储字符串响应,因此我可以将其与更改进行比较,因此如果没有检测到更改,可能会跳过updateChannelData(),我可以做什么轻量级添加此实现?< / p>

1 个答案:

答案 0 :(得分:0)

要进一步解释,您需要

  1. 下载您的xml文件内容并保存在班级或更高级别 全球层面
  2. 每次下载xml文件时,请与之前保存的文件进行比较 进行反序列化(如果你只是比较它是否已经改变,你不应该这样做)
  3. 使用更快/更高效的解串器,这样您就不必浪费 你的空间
  4. 注意:为了获得更高的性能/或者如果您的XML文件很大,那么在实际继续下载之前,您应该考虑只读取标题以查看content length是否已更改。

    实际实现可能如下所示:

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