2011-08-22 10 views
5

La mia applicazione è un misto di codice C# e C++. Modulo di avvio scritto in carichi C# durante la fase di inizializzazione Modulo C++ tramite meccanismo COM (Component Object Model). Tutto funzionava correttamente fino a quando ho deciso di aggiungere alla parte C# un servizio wcf. Tutte le chiamate di servizio wcf vengono instradate al codice C++ tramite COM. Dopo aver aggiunto alcuni nuovi metodi ho notato perdite di memoria nella finestra di output. Così ho aggiunto breakpoint al descrittore della classe C++ come si può vedere dallo screenshot. Da questo momento in poi cose strane hanno iniziato ad accadere. Dopo che il programma raggiunge il punto di interruzione, si arresta in modo imprevisto. La prima cosa strana è che quando eseguo il programma senza il punto di interruzione impostato, termina con grazia. La seconda cosa strana è che il modo in cui il programma si blocca è come se fosse eseguito senza debugger. Dopo aver fatto clic sul pulsante "Apri nel debugger" (o qualcosa di simile a questo) ricevo un messaggio di errore: "Il programma è già aperto nel debugger". Nessun messaggio nella finestra di output che potrebbe indirizzarmi all'origine dell'errore, nessun codice sospetto. Quando si aggiunge una finestra di messaggio al distruttore che inizia, viene visualizzata per una frazione di secondo e quindi l'intera applicazione si chiude (senza aggiungere all'utente l'opportunità di leggere cosa è visualizzato nella finestra del messaggio). Alla disperata ricerca di qualche indizio.Arresto anomalo strano durante il debug del distruttore di oggetti COM

P.S. I problemi si verificano solo quando il metodo wcf è stato chiamato almeno una volta. Non dipende se il flusso del programma in questa particolare chiamata è stato indirizzato al livello C++ o meno.

enter image description here

enter image description here

+0

Provare a utilizzare WinDbg anziché il debugger VS per ottenere maggiori informazioni sull'arresto – SpaceghostAli

risposta

0

risolto dal seguente codice:

public void Dispose() 
{ 
    Marshal.Release(internal_interface_ptr); 
    internal_interface_ptr = IntPtr.Zero; 
    Marshal.ReleaseComObject(internal_interface); 
    Marshal.ReleaseComObject(internal_interface); 
    internal_interface = null; 
} 

Accanto a questa altra domanda è stata appesa in codice C++. Quindi, per concludere, l'errore principale da parte mia era dimenticare di rilasciare esplicitamente l'oggetto COM nel codice C#. Anche se il garbage collector accetta l'operazione di gestione della memoria, ciò non è vero per i moduli scritti in altri linguaggi di programmazione. Il distruttore COM è stato chiamato molto recentemente quando una particolare libreria collegata dinamica doveva essere scaricata dalla memoria e questo ha causato problemi. Spero di averlo spiegato abbastanza chiaramente.

1

Quando si chiama C# da C++ a volte il garbage collector non correttamente vengono chiamati prima della fine del programma. Prova a forzare la garbage collection alla fine del tuo codice C#.

+0

Arresto anomalo come se il miracolo svanisse, tuttavia il programma termina prima che tutti i distruttori COM finissero il loro lavoro. Guarda il mio secondo screenshot. In questo momento preciso il programma è appena prima della sua fine, ma alcuni distruttori COM non sono ancora stati chiamati. Dopo che sono stati chiamati, il loro lavoro è finito all'improvviso. – truthseeker

+0

Risolto dal seguente codice: vuoto pubblico Dispose() { Marshal.Release (internal_interface_ptr); internal_interface_ptr = IntPtr.Zero; Marshal.ReleaseComObject (internal_interface); internal_interface = null; } – truthseeker

+0

Non sono abbastanza sicuro di cosa intendi con "Schiantarsi come se il miracolo sparisse". Penso che potrebbe essere necessario forzare i servizi a smaltire prima di chiamare il garbase collector. Verificare che ServiziToRun o servizi siano stati eliminati prima che il collector garbase sia eseguito altrimenti non funzionerà. – mydogisbox

Problemi correlati