2009-12-10 4 views
2

Possible en double:
How to properly clean up Excel interop objects in C#Pourquoi Excel reste-t-il ouvert?

J'ai cette fonction que j'utilise pour calculer la tendance linéaire de certaines données:

private string Trend(object conocido_y, object conocido_x, object nueva_matriz_x) 
{ 
    string result = String.Empty; 
    try { 
     Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
     result = ((Array)xlApp.WorksheetFunction.Trend(conocido_y, conocido_x, nueva_matriz_x, true)).GetValue(1).ToString(); 
     xlApp.Quit(); 
     System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 
     xlApp = null; 
    } 
    catch (System.Runtime.InteropServices.COMException ex) { 
     DError.ReportarError(ex, false); 
    } 
    catch (Exception ex) { 
     DError.ReportarError(ex); 
    } 
    return result; 
} 

les résultats sont très bien, mais la excel app ne ferme pas, si j'ouvre le gestionnaire de tâches le processus est toujours en cours, pourquoi?

+0

Mais la « bonne réponse » n'est pas celui qui est accepté, parce qu'il ne fonctionne pas pour le questionneur. Il n'a même pas un seul vote (je vais maintenant l'augmenter). –

Répondre

8

Je me souviens avoir vu que, après ReleaseComObject(), un GC forcé la passe est due pour que l'objet soit libéré et excelle pour finalement mourir.

En outre, je ne le vois pas dans cet extrait, mais vous devez ReleaseComObject() dans n'importe quelle feuille ou autre objet Excel sur lequel vous avez peut-être manipulé (le résultat est-il une telle chose?).

ReleaseComObject(result); 
app.Aplication.Quit(); 
ReleaseComObject(app); 
GC.Collect(); 
+0

@Vinko Merci Vinko c'était tout! – Unlimited071

1

Essayez d'utiliser

xlApp.Application.Quit(); 

au lieu de

xlApp.Quit(); 

Je suis tombé sur la même question récemment :)

+0

@Jon remercie Jon pour une réponse si rapide. J'ai essayé votre suggestion mais le problème reste, d'autres idées? – Unlimited071

+1

N'avez-vous pas dû forcer le GC et autres? Je me souviens que même Application.Quit() ne suffit pas (je n'ai pas ce code ici, donc je peux me tromper.) –

+0

@Vinko: Je n'ai pas, mais j'utilise. NET 4.0 - peut-être que cela fait une différence? –

2

Votre fonction crée-t-elle une erreur? Si c'est le cas, le Quit() n'est jamais atteint. Vous pouvez placer le Quit et ReleaseComObject dans un bloc finally.

+0

C'est une bonne idée en effet, même si cela ne résoudra probablement pas le problème. –

+0

Oui, je viens de relire votre question et vous avez dit que les résultats étaient ok, donc probablement pas le problème. J'ai le même problème où Excel apparaît encore dans la tâche mgr. Après un certain temps, ils s'en vont, donc c'est probablement une chose du GC. – Crispy

+0

@Chris. Comment cela a-t-il échappé à mon esprit ?! Faire des changements tout de suite! merci pour la prise. – Unlimited071

0

Excel est un serveur COM Automation.

Même si vous appelez Application.Quit() et que vous libérez la référence à l'objet COM, l'exe lui-même ne se terminera pas. Vous pourrez toujours le voir dans le gestionnaire de tâches. Faire d'autres appels à Excel utilisera l'instance en cours d'exécution.

L'instance Excel se ferme après la fermeture de votre application (thread, session, etc.).

Vous avez déjà des erreurs COM de type "serveur RPC non trouvé/en cours d'exécution"? Maintenant tu sais pourquoi.

Voir aussi (ce qui a été demandé à plusieurs reprises sur le SO):

c# and excel automation - ending the running instance

+0

a) Pourquoi GC.Collect le termine (de manière fiable et reproductible)? b) Qu'est-ce que "serveur RPC non trouvé/en cours d'exécution" a à voir avec cela? –

+0

a. Pourquoi pas? b. C'est une information intéressante applicable aux serveurs COM comme Excel. Vous pourriez obtenir cette erreur pour faire d'autres appels à Excel après l'avoir fermé et ne pas publié de références à celui-ci. –

+0

a) Je suis en train de dire que le GC-ing, sans quitter l'application, met fin à l'instance Excel, ce que vous dites n'est possible qu'après la fin de votre thread ou application b) Ok, maintenant c'est logique. –

Questions connexes