Oppførsel av unntakene innenfor delegater i C # 2 arrangert av MS Excel og COM

stemmer
3

Morgen alle,

Litt av en språkteori spørsmålet her ... Jeg har funnet noen referanser på nettet tyder på at avvikshåndtering og delegater i C # har noen annen atferd i noen tilfeller, men jeg kan ikke finne noen konkret dokumentasjon om saken.

Vi har nylig hatt noen store problemer med unntak inne representanter for en Microsoft Excel-tillegg som forårsaker en hard-krasj i MSVC runtime. Fjerne delegater løst dette, men jeg er nå glad i å finne ut blodig detaljer.

Som en konsis eksempel av kjernen kode:

Delegate del; // initialized elsewhere
try
{
    del.DynamicInvoke();
}
catch(Exception e)
{
    /* Parsing of exception to generate user-friendly message here */
}

Den ovennevnte konstruksjon tillot en sentralisert form for feilhåndtering og fra et rent kode synspunkt var ren og konsis. Hver offentlig eksponerte funksjon ble erklært som en representant og utført via det ovennevnte fragment.

I en enkel konsoll app, kaster et unntak fra representanten eller bare en vanlig uventet feil (f.eks tilfeldigvis kaller toString () på en nullpeker) fungerer som forventet, og feilen blir håndtert som ønsket.

Kast i MS Excel, og du får hard-krasj. Stepping gjennom koden vil vise hvor feilen oppstår, men ingen stabelen slappe ser ut til å skje før alt kommer ned i en stor ildkule av ødeleggelse.

Min hypotese er at COM, hosting .NET runtime (og dermed vår kode) gjør noe annet til vanlig kjøring NET-kode. Dette dreper endepunktet og Excel ikke vet dette, som igjen prøver å få tilgang til endepunktet via COM bare å finne det har liksom forsvunnet og Excel craps ut i retur.

Dette skjer bare med kombinasjonen av Excel + COM + delegater, men jeg vet ikke ærlig vet som er mer innflytelsesrike i dette problemet ... noen tanker?

Publisert på 17/10/2008 klokken 08:53
kilden bruker
På andre språk...                            


4 svar

stemmer
0

Side Merk: Hele ideen med unntak fanger er ikke å "svelge" dem og vise feilmeldingen, men å komme seg, om mulig fra situasjonen, samt opprydding ressurser.

Bedre utnyttelse prøve / fangst uansett hvor du trenger (dvs. rundt kode som kan kaste), og deretter ringe en vanlig funksjon for å vise / log problemet.

Også, hvis du bruker forskjellige tråder for å få tilgang Excel COM objekter en mye rart kan skje.

For riktig svar på spørsmålet ditt er behov for mer informasjon:

  1. Skjer det alltid?
  2. Hvis ikke, når du ser problemet er det et klart unntak, eller en kastet fra en Excel-objekt?
  3. Kan du lage en enkel metode, som bare kaster et unntak (kaste nytt ApplicationException ();), og se om du fortsatt har problemet?

Jubel

Svarte 17/10/2008 kl. 17:34
kilden bruker

stemmer
1

Jeg tror det du kan finne her er at du ikke slipper MS Excel COM-objekter du implisitt skaper når et unntak. I min erfaring MS Office-programmer er svært følsomme for sine ressurser ikke blir utgitt (selv om det meste av min erfaring er med Outlook).

Jeg ville pleier ikke å prøve å håndtere COM-basert unntak på denne måten hvis det er mulig. Hvis du ønsker centalized logging, se på Application.ThreadException (for WinForms app) og AppDomain.CurrentDomain.UnhandledException stedet.

Innsiden av funksjoner, kan det være lurt å ringe Marshal.ReleaseComObject () i dine metoder endelig {} blokker for å sørge for at Excel ikke blir skadet når unntak blir kastet.

Svarte 19/10/2008 kl. 15:36
kilden bruker

stemmer
0

Unnskyldninger for sent svar - travel uke!

Hele ideen om unntak fanger er ikke å "svelge" dem og vise feilmeldingen, men å komme seg, om mulig fra situasjonen, samt opprydding ressurser.

Yup, det er ideen, men i praksis er det ikke alltid ut som en ren. Koden i spørsmålet her er egentlig en mellommann, og ofte kan ikke vite om vil oppstå en feil, og hvis man tilfeldigvis det ikke kan vite hva brukeren faktisk prøver å gjøre og dermed auto gjenopprette.

Skjer det alltid?

Ja, hvis det er en uventet unntak og det synes alltid som en .NET en opprinnelse i C # /. NET kode

lage en enkel metode, som bare kaster et unntak (kaste nytt ApplicationException ();), og se om du fortsatt har problemet?

Nei, kaste våre egne unntak fungerer fint hver gang. Det er bare hvis runtime selv genererer unntak av at vi får harde krasjer.

du ikke slippe MS Excel COM-objekter du implisitt skaper når et unntak

Dette høres plausibelt. En VBA lag passerer data fra Excel i løpet COM og inn NET, så det kan godt være å gjøre noe funky med ressurs eierskap.

Hvis du ønsker centalized logging, se på Application.ThreadException (for WinForms app) og AppDomain.CurrentDomain.UnhandledException stedet.

Jeg fikk ikke se inn tidligere, men sistnevnte ville aldri bli kalt. En av mine første forsøk var å fange den på AppDomain nivå forutsatt at, uansett grunn, ble en representant basert unntak slipping gjennom nettet.

kan det være lurt å ringe Marshal.ReleaseComObject ()

Interessant, jeg var ikke klar over denne funksjonen. Vi har stort sett ignorert noen eksplisitt COM-kode og gått med minstekravet og håp (!) Som .NET CLR gjør sin magi ...

Jeg har jobbet rundt det nå ved å fjerne delegatene og alt virker fornøyd. Må bare huske å være forsiktig (eller direkte unngå) delegater og unntak i fremtiden Kontor + VBA + COM + CLR kode :-)

Svarte 21/10/2008 kl. 10:35
kilden bruker

stemmer
0

En grunn jeg føler er på grunn av det faktum at representanten er å påberope seg faktiske koden som kaster unntak i en annen tråd. så unntaket i en annen tråd som ble kalt async ikke ville være fangst i gjeldende tråd som gjeldende tråd funksjon ville mest avkjørsel før async Invoke utfører.

Svarte 16/02/2009 kl. 11:45
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more