Hans Passant es, por supuesto correcta. Si Monitor.Enter
arroja antes de se toma la cerradura, entonces usted hace no quiere que finalmente se ejecute. Si arroja después de se toma el bloqueo y después de se ingresa la prueba, luego se libera el bloqueo. (Más sobre esto más adelante.) Pero si el lanzamiento ocurre después de que se toma el bloqueo pero antes de se ingresa la prueba, y luego el bloqueo nunca se limpiará.
This is a rare but possible situation.
En C# 4 cambiamos el codegen de la declaración de bloqueo para que el monitor ingrese está dentro del intento. Esto asegura que el bloqueo siempre se libera si algo se lanza después de que se realiza el bloqueo. Sin embargo, tenga en cuenta que esto aún podría estar equivocado. Si se lanza algo después de que se haya activado el bloqueo, entonces ¡cualquiera que sea la mutación no atómica que protege el bloqueo puede completarse a medias, y el bloque finally desbloquea el bloqueo y permite el acceso al estado incoherente! El problema fundamental aquí es que no deberías tirar dentro de un candado en primer lugar.
Consulte my article about the issue para obtener más información.
Tener Enter() dentro del bloque try es un error. Llamarás a Exit() cuando podría no haber ingresado(). Solo tendría que sufrir un dolor de estómago por una excepción planteada * después de * la llamada Enter(), * antes de * ingresar al bloque try. Que de hecho era un error en la inestabilidad x64: http: //www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx También la motivación detrás de la nueva sobrecarga de 4.0 Monitor.Enter (object, ref bool). –