2012-02-13 20 views
5

So che questo è stato discusso in precedenza ma non sono riuscito a trovare una risposta soddisfacente.Rilascio dell'oggetto COM in C#

Ho un file di posta elettronica (.msg) che apro come di seguito e quindi chiama Display.

oApp = new Microsoft.Office.Interop.Outlook.Application(); 
mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 
mail.Display(false); 
oApp = null; // do I need to release this object ? 

gli utenti possono chiuderlo e riaprirlo. Prima di fare clic su "riapri", controllo se la finestra esiste ancora, se sì, quindi manda un SetForeground (hwnd) a quella finestra. in caso contrario, significa che l'utente lo ha chiuso, quindi rilascia l'oggetto mailItem e apri di nuovo.

public static void ReleaseCOMObject(Microsoft.Office.Interop.Outlook.MailItem item) { 
     int r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     while (r != 0) { 
      r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     } 
    } 

Se provo ad aprire nuovamente lo stesso file. Esso "a volte" genera un "file in uso di eccezione" Quindi, penso che anche se sto rilasciando il MailItem .. non è stato rilasciato correttamente.

Cosa posso fare per assicurarmi che venga rilasciato correttamente. chiudere e riaprire un file è uno scenario molto comune.

Qualsiasi suggerimento sarà molto utile.

+1

Si dovrebbe "rilasciare" solo quando si incrementa il contatore di riferimento, "rilasciare" altri riferimenti a persone può causare problemi. – Matthew

risposta

6

Se si utilizzano le funzionalità di interoperabilità COM di .NET (siete), non dovreste preoccuparvi di ciò.

Conteggi di riferimento tracce COM - e quando il conteggio ref raggiunge 0 oggetti COM vengono rilasciati automaticamente - e .NET si occupa di lavorare con il meccanismo di conteggio di riferimento COM standard per voi.

Se eri P/Invoca in una libreria C le cose potrebbero essere diverse - ma non dovresti avere preoccupazioni in uno scenario standard come il tuo.

+0

Non sono sicuro di cosa sto facendo male. Ho notato che una volta ottenuto "File In use Exception", riavvio il mio outlook fare il trucco. Che tipo di pulizia ho bisogno per "oApp = new Microsoft.Office.Interop.Outlook.Application();" ? – karephul

+2

Funziona ora -> C'era un altro modulo che stava trattenendo il MailItem e non lo stava rilasciando. – karephul

+0

BTW, volevo solo farti sapere che dovevo ancora "ReleaseCOMObject" per farlo funzionare. – karephul

3

fare le cose come questa:

mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 

causerà i riferimenti di non essere smaltiti anche quando si chiama ReleaseComObject perché il riferimento all'oggetto bambino non è stato smaltito correttamente.

Si dovrebbe effettuare le chiamate di questo tipo:

session = oApp.Session; 
mail = (Microsoft.Office.Interop.Outlook.MailItem)session.OpenSharedItem(fileName); 

E si dovrebbe disporre di ciascuno di questi sotto-oggetti, come la sessione, a sua volta.

+0

Ho notato che se Outlook non è in esecuzione sulla mia macchina .. chiusura e riapertura (il modo che ho descritto in precedenza) funziona bene. Penso che in qualche modo Outlook stia tenendo il riferimento a quel file. Qualche suggerimento lì? Ho provato a rilasciare separatamente anche l'oggetto Session (non funziona) – karephul

+0

Stai chiamando il maresciallo.Metodo ReleaseComObject nello stesso metodo in cui stai ricevendo l'elemento di posta o lo stai facendo in qualche gestore di eventi onclose o qualcosa del genere? – Nanhydrin

+0

Prima che l'utente possa aprire una mail, controlliamo se c'è una finestra con lo stesso titolo. In caso contrario, quindi ReleaseComObject (mailItem) .. e riaprire. [L'utente potrebbe aver chiuso la finestra di posta elettronica] .. Fondamentalmente tengo il MailItem finché posso in modo che possa salvarlo periodicamente. – karephul