自定义C#控件加载缓慢,占用大量内存

自定义C#控件加载缓慢,占用大量内存,c#,wpf,winforms,wpf-controls,C#,Wpf,Winforms,Wpf Controls,我有一个控件,它有一个标签、轨迹栏和两个文本框。我有一个表单,每个选项卡可以有0-25个这样的表单,它们在运行时加载从包含完整构建程序的文件夹或项目文件夹中的XML文件解析的数据。我不明白为什么控件加载得这么慢,占用了这么多内存 控件放置在表单上,在加载表单时以及更改到每个选项卡时调用以下代码,因为默认情况下它们都是延迟加载的 public msgInfoControl() { InitializeComponent(); } public vo

我有一个控件,它有一个标签、轨迹栏和两个文本框。我有一个表单,每个选项卡可以有0-25个这样的表单,它们在运行时加载从包含完整构建程序的文件夹或项目文件夹中的XML文件解析的数据。我不明白为什么控件加载得这么慢,占用了这么多内存

控件放置在表单上,在加载表单时以及更改到每个选项卡时调用以下代码,因为默认情况下它们都是延迟加载的

    public msgInfoControl()
    {
        InitializeComponent();
    }

    public void init(string s, UInt16 insize, UInt32 init_val, UInt32 init_min, UInt32 init_max, double mult, double inos, msg inMsg, Point inGridLoc = new Point(), string anotherName="")
    {

        // set the min and max value for the trackbar
        set_min_max(init_min, init_max);

        // initialize the trackbar value
        trackbar.Value = (int)init_val;

        // make the text in teh text box update to reflect the initial value
        trackbar_Scroll(null, null);
        myMsg = inMsg;

        this.Tag = inMsg;

        name.Text = s;
        otherName = anotherName;
        int xGridLoc;
        int yGridLoc;
        if (inGridLoc.IsEmpty)
        {
            xGridLoc = ((this.Location.X + 85) / 184);
            yGridLoc = ((this.Location.Y) / 69);
        }
        else
        {
            xGridLoc = inGridLoc.X;
            yGridLoc = inGridLoc.Y;
        }

        myGridLoc = new Point(xGridLoc, yGridLoc);

        // initialize the SPN
        myMsgInfo.init(insize, init_val, init_min, init_max, mult, inos);
    }

    public void set_min_max(UInt32 inmin, UInt32 inmax)
    {
        trackbar.Minimum = (int)inmin;
        trackbar.Maximum = (int)inmax;

        trackbar.SmallChange = 1;
        trackbar.LargeChange = (int)((inmax - inmin) / 4);
    }
XML读取器方法

public void start1939Control(RP1210Sim.msgInfoControl controlToInitialize, string spnName, ref msg inMsg, UInt16 sa = 0x00)
    {
        try
        {
            pgns = doc1939.Descendants("pgnid");
        }
        catch
        {
            return;
        }
        bool newPgn = (inMsg == null);
        List<XElement> spnlist = new List<XElement>();
        foreach (XElement ex in pgns)
        {
            foreach (XElement spnex in ex.Descendants("spn"))
            {
                spnlist.Add(spnex);
            }
        }
        int count = spnlist.Count;
        int i = 0;
        string j = "";
        string l = "";
        while ((!spnName.ToLower().Equals(l.ToLower()) && !spnName.ToLower().Equals(j.ToLower())) && i < count) //While you don't have text user looking for
        {
            j = spnlist[i].Attribute("name").Value;
            l = spnlist[i].Attribute("shortname").Value;
            if (!spnName.ToLower().Equals(j.ToLower()) && !spnName.ToLower().Equals(l.ToLower()))
                i++;
        }
        if (spnName.ToLower().Equals(j.ToLower()) || spnName.ToLower().Equals(j.ToLower()))
        {
            String z = spnlist[i].Attribute("name").Value;
            String s = spnlist[i].Attribute("shortname").Value + "   " + spnlist[i].Parent.Attribute("idhex").Value;
            UInt16 insize = Convert.ToUInt16(spnlist[i].Element("size").Attribute("value").Value);
            UInt32 inval = Convert.ToUInt32(spnlist[i].Element("start").Attribute("value").Value);
            UInt32 inmin = Convert.ToUInt32(spnlist[i].Element("min").Attribute("value").Value);
            UInt32 inmax = Convert.ToUInt32(spnlist[i].Element("max").Attribute("value").Value);
            double inmult = Convert.ToDouble(spnlist[i].Element("mult").Attribute("resolution").Value) * Convert.ToDouble(spnlist[i].Element("mult").Attribute("conversion").Value);
            double inos = Convert.ToDouble(spnlist[i].Element("offset").Attribute("value").Value);
            if (inMsg == null)//If the message hasn't been initialized yet
            {
                inMsg = new msg1939Gui(Convert.ToUInt32(spnlist[i].Parent.Attribute("id").Value));
                inMsg.changeSa(sa);
            }//If it has, just add the new SPN
            controlToInitialize.init(s, insize, inval, inmin, inmax, inmult, inos, inMsg, anotherName: z);
            ((msg1939Gui)inMsg).addNewController(controlToInitialize);

            inMsg.addMsgInfo(controlToInitialize.myMsgInfo, Convert.ToInt16(spnlist[i].Element("location").Attribute("value").Value));
            if (spnlist[i].Parent.Attribute("refresh").Value.Equals("100") && newPgn)
            {
                timerServ.create100MsTimers1939(inMsg);
            }
            else if (spnlist[i].Parent.Attribute("refresh").Value.Equals("1000") && newPgn)
            {
                timerServ.create1000MsTimers1939(inMsg);
            }
        }
        else
        {
            if (log != null)
                log.AppendText(spnName + " not found" + "\n");
        }
    }

你做过分析吗?您确定代码在您认为是时被调用了吗?我没有看到与您提到的xml文件读取/解析相关的任何内容,但是您的延迟加载可能没有您希望的那么延迟……我没有做任何分析。我只是带着断点走了过去。我应该发布主表单的init方法和实际调用此方法的方法。强烈建议您将XML反序列化为适当的强类型对象模型(使用类似.Net的
XmlSerializer
的方法,而不是自己手动解析所有内容),并使用
ItemsControl
绑定到该模型,与这个可怕的怪物相反。+1对于合适的词语选择(可怕的怪物),我想我会这样做,但是在我从XML文件读入之前,控件速度很慢,我非常感谢任何帮助诊断它速度慢的原因。
public RP1210SimulatorMainGUI()
    {
        InitializeComponent();

        xmlRead.start1939Control(engine_speed_control_engine1, "Engine Speed (RPM)", ref pgn61444);
        xmlRead.start1939Control(vehicle_speed_control_engine1, "Vehicle Speed (mph)", ref pgn65265);
        xmlRead.start1939Control(fuel_level_control_engine1, "Fuel Level (%)", ref pgn65276);
        xmlRead.start1939Control(total_fuel_control_engine1, "Total Fuel Used (G)", ref pgn65257);
        xmlRead.start1939Control(odometer_control_engine1, "Odometer (m)", ref pgn65248);
        xmlRead.start1939Control(accel_pedal_control_engine1, "Accel Pedal Position (%)", ref pgn61443);
        xmlRead.start1939Control(brake_pedal_control_engine1, "Brake Pedal Position (%)", ref pgn61441);
        xmlRead.start1939Control(total_idle_fuel_consumed_control_engine1, "Total Idle Fuel Used (G)", ref pgn65244);
        xmlRead.start1939Control(total_idle_hours_control_engine1, "Total Idle Hours", ref pgn65244);
        xmlRead.start1939Control(total_vehicle_hours_control_engine1, "Total Vehicle Hours", ref pgn65255);
        xmlRead.start1939Control(total_engine_hours_control_engine1, "Total Engine Hours", ref pgn65253);
    }