2010-01-18 10 views
2

J'écris une classe excel et je veux libérer cet objet non géré automatiquement. J'utilise un pattern IDisposable et j'écris des méthodes Dispose. Exemple;Comment libérer l'objet excel avec l'interface IDisposeable

class MSExcel : IDisposable 
{ 
    ApplicationClass excel; 
    bool disposed; 

    public MSExcel() 
    { 
     disposed = false; 
     excel = new ApplicationClass(); 
    } 

    public void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 

      if (disposing) 
      { 

      } 

      excel.Quit();     
      disposed = true; 

     } 
    } 

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

    ~MSExcel() 
    { 
     Dispose(false); 
    } 
} 

Mais j'ai une erreur classique sur exc.Quit(). "objet COM qui a été séparé de son RCW sous-jacent". Vous avez une erreur dans le code?

+1

"Jeter" est conçu pour libérer des objets, mais vous l'utilisez pour la logique de l'application, à savoir quitter Excel. Déplacez votre méthode de quitter ailleurs et ne comptez pas sur Dispose pour quitter Excel pour vous, vous devriez le faire vous-même. –

Répondre

2

Comme expliqué dans ma réponse à votre autre question connexe here, vous ne devez pas effectuer d'actions sur les types de référence à partir de votre finaliseur. Vous appliquez ceci en utilisant le paramètre bool disposing de votre méthode Disposed(bool), comme vous l'avez fait. Vous passez en true, quand Disposed(bool) est appelé explicitement à partir de la méthode void Dispose(), et passez en false lorsqu'il est appelé depuis votre finaliseur, ce que vous avez également fait. Cependant

, vous devez également protéger votre appel à excel.Quit() afin qu'il soit pas appelée lorsque Disposed(bool) est appelé par le finaliseur. Autrement dit, vous ne devez appeler que excel.Quit() lorsque l'argument bool disposing est true.

Par conséquent, le code de votre méthode Disposed(bool) devrait se présenter comme suit:

public void Dispose(bool disposing) 
{ 
    if (!this.disposed) 
    { 

     if (disposing) 
     { 
      excel.Quit(); 
     } 

     disposed = true; 
    } 
} 

Une fois fait, vous pourriez utiliser votre classe "MSExcel" comme suit:

using (MSExcel msExcel = new MSExcel) 
{ 
    // The code calling your 'MSExcel' object goes here. 
} 

En le faisant De cette façon, lorsque votre code atteindra le crochet fermant "}" de votre bloc using statement, la méthode Dispose de votre classe "MSExcel" sera appelée automatiquement, assurant que excel.Quit() est appelée de manière déterministe, et non pas à partir d'un finaliseur.

Hope this helps ...

Mike

+0

En supposant que l'on a affaire à la méthode Quitter de la classe Excel.Application, fournir la valeur True au premier paramètre (SaveChanges) empêche la suspension possible pendant le processus de fermeture, lorsqu'il y a des changements en attente. Cela devrait être une préoccupation majeure lorsque la propriété Visible d'Excel.Application est définie sur False, ce qui arrive principalement lors des processus d'automatisation. –