Winforms или XmlSerializer утечки? - PullRequest
0 голосов
/ 19 июля 2011

Приложение WinForms, с одним фоновым рабочим, делает что-то и ничего больше:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            progressBar1.Invoke(new MethodInvoker(() => { progressBar1.Value = 0; progressBar1.Maximum = Directory.GetFiles(configuration.xml.path).Count(); }));
            Directory.GetFiles(configuration.xml.path).ToList()
                .ForEach(
                p =>
                {
                    Message = XmlSerializerHelper<message>.Read(p);
                    Message.data.ToList().ForEach(www => 
                        { 
                            if (www.state == 0)www.state = 37; 
                        }
                    );
                    try
                    {
                        dataGridView1.Invoke(new MethodInvoker(() =>
                        {
                            var deb1 = Message.caption.source;
                            var deb2 = configuration.periods.Single(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).name;
                            var deb3 = dataGridView1.Rows.Cast<DataGridViewRow>().Select(o => o.Cells[0].Value.ToString()).Contains(Message.caption.source);
                            var deb4 = dataGridView1.Rows.Cast<DataGridViewRow>().Select(o => o.Cells[1].Value.ToString()).Contains(
                                configuration.periods.Single(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).name);
                            if (!dataGridView1.Rows.Cast<DataGridViewRow>().Select(o => new
                            {
                                source = o.Cells[0].Value.ToString(),
                                period = o.Cells[1].Value.ToString()
                            }).Contains(
                                new { 
                                    source = Message.caption.source,
                                    period = configuration.periods.Single(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).name }))                   
                            {
                                textBox1.Anchor = AnchorStyles.Bottom;
                                dataGridView1.Rows.Add(Message.caption.source, configuration.periods.Single(y => y.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).name, "0", "0", "0", "-");
                                if (dataGridView1.Rows.Cast<DataGridViewRow>().Count() > 7)
                                    this.Size = new System.Drawing.Size(this.Width, this.Height + 22);
                                dataGridView1.Size = new Size(dataGridView1.Width, dataGridView1.Height + 22);
                                textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
                            }
                        }));
                        Message.data.Where(q => q.value.Length > 0).ToList().ForEach(r =>
                            {
                                try
                                {
                                    r.value = r.value.Replace(',', '.');
                                    data.insObjParameterByCodeValueUpd(r.ucode, r.state, double.Parse(r.value, CultureInfo.InvariantCulture), DateTime.Parse(r.timestamp), null);
                                    dataGridView1.Invoke(new MethodInvoker(() =>
                                        dataGridView1.Rows.Cast<DataGridViewRow>().Single(u => 
                                            u.Cells[0].Value.ToString() == Message.caption.source.ToString() && 
                                            u.Cells[1].Value.ToString() == configuration.periods.Single(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString())
                                            .name).Cells["lasttime"].Value = DateTime.Now.ToString()));
                                    textBox1.Invoke(new MethodInvoker(() =>
                                            {
                                                textBox1.SelectionStart = textBox1.Text.Length;
                                                textBox1.SelectionColor = Color.Black;
                                                textBox1.AppendText(System.DateTime.Now.ToString() + " загружены " + configuration.periods.Single(m=>
                                                    m.list_parperiod_id == Message.caption.datatype).name.ToLower()+ " данные за "+ Message.caption.timestamp+ " от "+ Message.caption.source + ".\r\n");
                                            })
                                        );
                                    log.Write(System.DateTime.Now.ToString() + " загружены " + configuration.periods.Single(m =>
                                                    m.list_parperiod_id == Message.caption.datatype).name.ToLower() + " данные за " + Message.caption.timestamp + " от " + Message.caption.source + ".\r\n");
                                    if ((bool)e.Argument)
                                        dataGridView1.Invoke(new MethodInvoker(() =>
                                        {
                                            dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["collect"].Value =
                                        (int.Parse(dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["collect"].Value.ToString()) + 1).ToString();
                                        }
                                          ));
                                    else
                                        dataGridView1.Invoke(new MethodInvoker(() =>
                                        {
                                            dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["hand"].Value =
                                        (int.Parse(dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["hand"].Value.ToString()) + 1).ToString();
                                        }
                                        ));

                                }
                                catch (Exception ww)
                                {
                                    if (!InfoMessage.Send(ww.Message, configuration.webservice.address, configuration.source.name))
                                        log.Write(System.DateTime.Now.ToString() + " веб сервис недоступен.\r\n");
                                    dataGridView1.Invoke(new MethodInvoker(() =>
                                            {
                                                dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["unknown"].Value =
                                                (int.Parse(dataGridView1.Rows.Cast<DataGridViewRow>().Where(u => u.Cells[0].Value.ToString() == Message.caption.source.ToString() && u.Cells[1].Value.ToString() == configuration.periods.Where(c => c.list_parperiod_id.ToString() == Message.caption.datatype.ToString()).Select(c => c.name).First().ToString()).Single().Cells["unknown"].Value.ToString()) + 1).ToString();
                                            })
                                        );
                                    textBox1.Invoke(new MethodInvoker(() =>
                                            {
                                                textBox1.SelectionStart = textBox1.Text.Length;
                                                textBox1.SelectionColor = Color.Red;
                                                textBox1.AppendText(System.DateTime.Now.ToString() + " " + ww.Message + "\r\n");
                                                log.Write(System.DateTime.Now.ToString() + " " + ww.Message + "\r\n");
                                            })
                                        );
                                    log.Write(System.DateTime.Now.ToString() + " " + ww.Message + "\r\n");
                                    log.Write(System.DateTime.Now.ToString() + " " + ww.Message + "\r\n");
                                }
                            });

                        if (!checkBox2.Checked)
                            File.Delete(p);
                    }
                    catch (Exception e11)
                    {
                        if (!InfoMessage.Send(e11.Message, configuration.webservice.address, configuration.source.name))
                            log.Write(System.DateTime.Now.ToString() + " веб сервис недоступен.\r\n");
                        textBox1.Invoke(
                            new MethodInvoker(() =>
                                {
                                    textBox1.SelectionStart = textBox1.Text.Length;
                                    textBox1.SelectionColor = Color.Red;
                                    textBox1.AppendText(System.DateTime.Now.ToString() + " " + e11.Message + "\r\n");
                                    log.Write(System.DateTime.Now.ToString() + " " + e11.Message + "\r\n");
                                })
                            );
                        log.Write(System.DateTime.Now.ToString() + " " + e11.Message + "\r\n");
                    }
                    progressBar1.Invoke(new MethodInvoker(() => { progressBar1.Value++; }));
                });
        }
        catch (Exception ee)
        {
            if (!InfoMessage.Send(ee.Message, configuration.webservice.address, configuration.source.name))
                log.Write(System.DateTime.Now.ToString() + " веб сервис недоступен.\r\n");
            textBox1.Invoke(new MethodInvoker(() =>
                    {
                        textBox1.SelectionStart = textBox1.Text.Length;
                        textBox1.SelectionColor = Color.Red;
                        textBox1.AppendText(System.DateTime.Now.ToString() + " " + ee.Message + "\r\n");
                    })
            );
            log.Write(System.DateTime.Now.ToString() + " " + ee.Message + "\r\n"); 
        }
    }

XmlSerializer:

public static class XmlSerializerHelper<T>
{
    public static Type _type = typeof(T);



    public static MemoryStream Save(object obj) {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        XmlSerializer serializer = new XmlSerializer(_type);
        var memstr = new MemoryStream();
        serializer.Serialize(memstr, obj,ns);
        return memstr;
    }
    public static void Save(string path, object obj)
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        using (TextWriter textWriter = new StreamWriter(path))
        {
            XmlSerializer serializer = new XmlSerializer(_type);
            serializer.Serialize(textWriter, obj, ns);
        }

    }

    public static T Read(string path)
    {
        T result;
        using (TextReader textReader = new StreamReader(path))
        {
            XmlSerializer deserializer = new XmlSerializer(_type);
            result = (T)deserializer.Deserialize(textReader);
        }
        return result;
    }
}

это повторяется каждые 10 секунд по таймеру.после 2 слабых мест у этого приложения 150 Мб памяти.Что здесь может просочиться?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2012

XmlSerializer испытывает утечку памяти .

Я не знаю, происходит ли это в .NET 4.0, но оно остается в .NET 3.5.

Поскольку вы запускаете приложение winforms, это не так уж плохо, потому что ресурсы высвобождаются при закрытии приложения - если оно закрывается ...

Я столкнулся с этим случаем, написав службу Windows, в которой я использую интенсивную сериализацию XML и другие неуправляемые ресурсы. Неуправляемый код вышел из строя из-за сбоя памяти, и я изо всех сил пытался выяснить, откуда он взялся.

XmlSerializerCache из mvpxml библиотека спасает мою жизнь.

0 голосов
/ 19 июля 2011

после 2 слабых мест у этого приложения 150 МБ памяти.

нет

Ничто; это просто отлично. Память там для использования , и приложения не должны слишком стесняться ее использовать. Это не звучит так, будто это кровоточащая память; будь как будет.

...