PowerPoint VSTO выделяет все больше и больше памяти - PullRequest
0 голосов
/ 26 мая 2020

Я пишу VSTO, который проходит через все слайды, через все формы и устанавливает значение заголовка. Я понял, что потребление памяти увеличивается после каждого запуска. Поэтому я свернул свой код и позволил ему запускаться 100 раз, в результате чего на каждые 100 запусков выделяется около 20 МБ памяти.

Мой код запускается с помощью кнопки боковой панели, в презентации около 30 слайдов с заголовками. Мой код для кнопки выглядит так:

        private void button1_Click(object sender, EventArgs e)
    {
        SetTitle_Direct();

        Stopwatch watch = new Stopwatch();
        watch.Start();

        SetTitle_Direct();

        watch.Stop();
        //MessageBox.Show("Time spend: " + watch.Elapsed);

        AMRefreshProgress.Maximum = 100;
        AMRefreshProgress.Step = 1;
        AMRefreshProgress.UseWaitCursor = true;
        AMRefreshProgress.ForeColor = System.Drawing.ColorTranslator.FromHtml(ThisAddIn.amColor);


        for (int i = 1; i <= 100; i++)
        {
            SetTitle_Direct();
            AMRefreshProgress.PerformStep();
        }


        AMRefreshProgress.Value = 0;
        AMRefreshProgress.UseWaitCursor = false;


        Stopwatch watch2 = new Stopwatch();
        watch2.Start();

        SetTitle_Direct();

        watch2.Stop();
        MessageBox.Show("Time 1st run: " + watch.Elapsed + "\n Time 11th run: " + watch2.Elapsed);
    }

SetTitle_Direct () перебирает слайды:

        public void SetTitle_Direct()
    {
        PowerPoint.Presentation oPresentation = Globals.ThisAddIn.Application.ActivePresentation;

        foreach (PowerPoint.Slide oSlide in oPresentation.Slides)
        {

            if (oSlide.Shapes.HasTitle == OFFICECORE.MsoTriState.msoTrue)
            {
                oSlide.Shapes.Title.TextFrame.TextRange.Text = "Test Main Title";
            }



            for (int iShape = 1; iShape <= oSlide.Shapes.Count; iShape++)
            {
                if (oSlide.Shapes[iShape].Type == Microsoft.Office.Core.MsoShapeType.msoPlaceholder)
                {
                    if (oSlide.Shapes[iShape].PlaceholderFormat.Type == PowerPoint.PpPlaceholderType.ppPlaceholderSubtitle)
                    {
                        oSlide.Shapes[iShape].TextFrame.TextRange.Text = "Test Sub Title";
                    }
                }
            }
        }
    }

Что заставляет AddIn выделять все больше и больше памяти - или как могло этого можно избежать?

1 Ответ

0 голосов
/ 26 мая 2020

При разработке надстройки на основе VSTO вы обычно имеете дело с COM-объектами (PowerPoint - это COM-сервер). При каждом вызове свойства или метода, который возвращает COM-объект, ссылка на объект обычно увеличивается, что приводит к сохранению объектов в памяти до тех пор, пока счетчик ссылок не уменьшится и не станет равным нулю. Итак, я бы рекомендовал использовать метод Marshal.ReleaseComObject , чтобы уменьшить ссылку на объект и позволить среде выполнения сохранять память и сокращать время жизни объектов.

Чтобы иметь возможность освободить каждый COM-объект, вы должны разделить длинные строки вызовов свойств и методов. Объявите каждое свойство или вызов метода в отдельной строке кода. Таким образом, вы сможете освобождать каждый объект и эффективно отлаживать код, если вокруг что-то странное.

Вы можете посмотреть Когда выпускать COM-объекты в надстройках Office, разработанных в. NET статья для получения дополнительной информации.

Другой альтернативный способ - использовать сборщик мусора:

GC.Collect
GC.WaitForPendingFinalizers
GC.Collect
GC.WaitForPendingFinalizers
...