2016-10-21 6 views
-1

создать простую надстройку для точки питания и это кодрелиз PowerPoint Interop Com экземпляр член класса в C#

pp.Application ppApplication = new pp.Application(); 
private void Ribbon1_Load(object sender, RibbonUIEventArgs e) 
{ 
    ppApplication.PresentationOpen += new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen); 
    ppApplication.PresentationClose += new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose); 
} 
void ppApplication_PresentationOpen(pp.Presentation Pres) 
{   
} 
void ppApplication_PresentationClose(pp.Presentation Pres) 
{ 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     Marshal.FinalReleaseComObject(ppApplication); 
} 

точка питания никогда не закрывается, если ppApplication глобален. Я думаю, что доза глобального com-объекта не распространяется таким образом. Что мне делать?

+1

Почему вы используете 'new pp.Application()' в надстройке PowerPoint? У вас должен быть член 'this.Application'. Кроме того, у C# нет «глобальных» переменных, что вы подразумеваете под этим? – CodeCaster

+0

Обработчики событий на ppApplication могут создавать зависимость, которая предотвращает освобождение ppApplication. Попробуйте удалить обработчики обработанных событий, когда вы попадете в событие PresentationClosed. – PhillipH

ответ

1

Вы должны применить шаблон Dispose/Finalize, чтобы освободить неуправляемый ресурс должным образом. Это гарантирует, что как только ваш класс будет удален, все неуправляемые члены класса (а не глобальные переменные) будут выпущены. См https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx

using System; 
using System.Runtime.InteropServices; 

namespace PowerPointTestApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (Container c = new Container()) 
      { 
       Console.WriteLine("Opened.."); 
      } 

      Console.WriteLine("Closed.."); 
     } 
    } 

    public class Container: IDisposable 
    { 
     Microsoft.Office.Interop.PowerPoint.Application pp = new Microsoft.Office.Interop.PowerPoint.Application(); 

     public Container() 
     { 
      pp.PresentationOpen += (pres)=> 
      { 
       //DoSomething 
      }; 

      pp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue; 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     protected virtual void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       pp.Quit(); 
       Marshal.FinalReleaseComObject(pp); 
      }   
     } 

     ~Container() 
     {    
      Dispose(false); 
     } 
    } 
} 
+0

@CodeCaster Я работаю над примером – Alex

+0

@codeCaster Я действительно заинтересован в комментариях о правильности примера, который я привел для правильного удаления объектов interop. Может быть, кто-то может дать некоторые комментарии к этому подходу, поскольку об этом много мнения. – Alex

1

В соответствии с рекомендацией в этой должности Proper way of releasing COM objects?

1) Declare & instantiate COM objects at the last moment possible. 
2) ReleaseComObject(obj) for ALL objects, at the soonest moment possible. 
3) Always ReleaseComObject in the opposite order of creation. 
4) NEVER call GC.Collect() except when required for debugging. 

Вы должны позвонить

pp.Application ppApplication = new pp.Application(); 

в Ribbon_Load

Также вы асимметричны в вашем COM Инстанцирование и Rele ase - вы создаете экземпляр при инициализации класса (т. как a = new() в объявлении переменной), но отпустите, когда презентация закрыта. Закрытие презентации - это не то же самое, что закрытие приложения - лента, вероятно, все еще доступна, и это придет, чтобы укусить вас.

Последний пункт является то, что вы никогда не отцепить события вы подключили в объект COM, вы должны, по крайней мере, делать

ppApplication.PresentationOpen -= new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen); 
    ppApplication.PresentationClose -= new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose); 

для освобождения обработчиков событий, в противном случае у вас есть какие-то нежить ссылки.

 Смежные вопросы

  • Нет связанных вопросов^_^