visual teclas tag redimensionar que otro mueva hacer habilitar formulario evitar deshabilitar como botones bloquear abrir c# exception-handling synchronization

teclas - habilitar y deshabilitar botones en c#



bloqueo de un recurso a través de bloqueo dentro de intentar. ¿Esta mal? (3)

¿Hay algo de malo en usar el bloqueo con un bloque try? Recuerdo haber leído en alguna parte que siempre deberíamos tratar de poner una cantidad mínima de código dentro del bloque try y el bloqueo interno usa un bloque try-finally, ¿ven algo malo aquí? Necesito lidiar con el hecho de que el código dentro de ese bloqueo bloque puede lanzar excepción

try { lock(syncblk) { // do some processing } } catch(Exception e) { // do something with exception }


Necesito lidiar con el hecho de que el código dentro de ese bloqueo de bloqueo puede generar una excepción

Y ahí está tu problema. Esa es una situación terrible en la que estar.

¿Por qué estás encerrado en primer lugar? Por lo general, la razón por la que bloquea algo es porque desea implementar la siguiente lógica:

  • cierra la puerta
  • hacer un lío
  • limpialo
  • quitale el seguro a la puerta

Si haces eso, entonces nadie que honre la puerta cerrada con llave verá el desorden.

Por ejemplo, es posible que desee intercambiar valores de las variables "izquierda" y "derecha" de una manera segura para subprocesos, de modo que:

  • tomar la cerradura
  • lee la variable izquierda en tempLeft
  • lee la variable correcta en tempRight
  • escribe tempLeft en la derecha
  • acabamos de hacer un lío; El valor original de ''right'' ha desaparecido.
  • escribe tempRight en la izquierda
  • Hemos limpiado el desorden, todo está bien con el mundo otra vez.
  • libere la cerradura

Ahora supongamos que se lanza una excepción después de que se hace el desastre. ¿Lo que pasa? Saltamos directamente al desbloqueo, dejando el desorden para que otro hilo lo vea .

Por eso nunca debes lanzar una excepción dentro de una cerradura ; ¡Vence completamente el propósito de la cerradura! El objetivo principal de un bloqueo es asegurar que siempre se observe que el estado es consistente en todas las roscas, excepto en la responsable de limpiar el desorden.

Si tiene una excepción que puede ser lanzada desde dentro de una cerradura, lo mejor que puede hacer es salir de esa situación horrible. Si no puede hacer eso, entonces asegúrese de que (1) puede destruir el proceso por completo tan pronto como la excepción escapa del bloqueo, de modo que el desastre que hizo no pueda causar pérdida de datos u otro daño; haga un FailFast y Rompe el proceso desde la órbita, es la única forma de estar seguro, o (2) escribe el código de retroceso que deshace cualquier operación que estuvieras intentando antes de salir del bloqueo; es decir, limpiar el desastre de nuevo al estado original.

Si esta última es su estrategia, entonces no ponga el bloque try fuera de la cerradura; es inútil allí porque el control instantáneo deja el bloqueo a través de la excepción que otro subproceso puede bloquear y morir debido al desastre que dejaste expuesto . Pon el intento que trata con la excepción dentro de la cerradura:

lock(whatever) { try { MakeAMess(); } finally { CleanItUp(); // Either by completing the operation or rolling it back // to the pre-mess state } }

Si tiene fuertes requisitos de confiabilidad, tratar con secciones críticas bloqueadas que pueden generar excepciones es una tarea de programación extremadamente difícil que es mejor dejar a los expertos; Podría considerar usar una región de ejecución restringida si se encuentra mucho en esta situación.


Creo que puedes hacerlo a tu manera, pero aquí está la descripción de MSDN bloqueada para tu información. Consulte http://msdn.microsoft.com/en-us/library/ms173179.aspx para obtener más información.

El uso de la palabra clave lock (C #) o SyncLock (Visual Basic) generalmente se prefiere a usar la clase Monitor directamente, ya que lock o SyncLock es más conciso y porque lock o SyncLock asegura que el monitor subyacente se libere, incluso si el código protegido lanza una excepción. Esto se logra con la palabra clave finally, que ejecuta su bloque de código asociado independientemente de si se lanza una excepción.

Por lo tanto, no estoy seguro de a qué tipo de excepción se refiere, pero si le preocupa que no pueda liberar el bloqueo debido a una excepción, no tiene que preocuparse por ello.


Siempre puedes usar la sintaxis más larga así:

System.Threading.Monitor.Enter(x); try { ... } catch(Exception e) { } finally { System.Threading.Monitor.Exit(x); }