Følgende stump kode er den anbefalede måde at bruge monitors på, og det er identisk med den kode, som C#'s lock statement genererer.

Monitor.Enter(lockobject);
try
{
    //...
}
finally
{
    Monitor.Exit(lockobject);
}

 

Der er faktisk en potentiel bug i denne kode (iflg. Joe Duffy).  Kompileren er i sin fulde ret til at indsætte instruktioner mellem Monitor.Enter og try.  Et forsøg viser, at C# kompileren ganske rigtigt indsætter en NOP instruktion i debug build. 

Det betyder, at man (hvis man er meget uheldig) kan opleve asynkrone thread exceptions for netop denne instruktion.  Det kan f.eks. ske, hvis en anden tråd kalder Thread.Abort.  Sker det, vil finally blokken aldrig eksekvere, og vi har en såkaldt abandoned monitor.  Det er nok de færreste, for hvilke det er et reelt problem, men det kan ske.

Det viser sig, at C# teamet har taget højde for dette.  I release builds vil C# kompileren ikke indsætte ekstra instruktioner efter Monitor.Enter, og Monitor.Enter er lavet på en speciel måde, så næste instruktion i vores kode ovenfor vil foregå inde i try blokken.

Joe Duffys bog fik mig til at tænke på connections.  Hvis DbConnection.Open står uden for try blokken, kan man i sjældne tilfælde risikere, at finally blokken indeholdende DbConnection.Close ikke bliver kaldt pga. en exception.  Heldigvis er det et krav til DbConnection.Close, at man skal kunne kalde den flere gange uden at få en exception i hovedet uanset om ens connection er åben eller ej.  Derfor kan man med sindsro flytte DbConnection.Open indenfor try blokken.