none
Problema de funcionamiento de synclock RRS feed

  • Pregunta

  • Hola a todos:

    Estoy con la duda de que si el método synclock me funciona o lo tengo mal aplicado, ya que me produce alguna excepción de elemento bloqueado.

    Os paso a mostrar como lo tengo montado, entendiendo que tanto Accesologica.FormulasI y Accesologica.Formulas2 son dos procedimientos que a su vez agrupan un número elevado de procedimiento para cálculos de fórmulas, con select y updates.

    Proceso:

    'Variables para las hebras Private CargaFormulasParaGrupoII As Object = New Object Private CargaFormulasParaGrupoI As Object = New Object Private mensajes As String() = {"Carga Total Formulas Grupo I", "Carga Total Formulas Grupo II", "Carga Total Formulas Grupo III", "Carga Total Formulas Grupo IV"}

    'Declaro los hilos Dim t1 As New Thread(AddressOf FormulasGrupoI) Dim t2 As New Thread(AddressOf FormulasGrupoII) Dim t3 As New Thread(AddressOf FormulasGrupoIII) Dim t4 As New Thread(AddressOf FormulasGrupoIV) Public Event HiloCompleto(ByVal Grupo As Thread) Private Sub ActivaciónFormulas() VarGlobal.FormulasActivadasGrupoI = True VarGlobal.FormulasActivadasGrupoII = True VarGlobal.FormulasActivadasGrupoIII = True VarGlobal.FormulasActivadasGrupoIV = True End Sub Private Sub InicioCargaModulos() Dim a As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly Dim rm As New ResourceManager(a.GetName.Name & ".Textos", a) FormulasCargaHilos() Panel1.Visible = True Label29.Visible = True lblInfo.Visible = True Label23.Visible = True lblInfo.Text = "Generando carga de fórmulas ..." Label23.Text = rm.GetString("InicianCargaGrupo") & ": I, II, III y IV" '"Iniciando carga grupos" ProgressBar1.Visible = True ProgressBar1.Style = ProgressBarStyle.Marquee Timer2.Start() End Sub Private Sub FormulasCargaHilos() SyncLock CargaFormulasParaGrupoI FormulasGrupoI() End SyncLock SyncLock CargaFormulasParaGrupoII FormulasGrupoII() End SyncLock FormulasGrupoIII() FormulasGrupoIV() End Sub Private Sub Timer2_Tick(sender As System.Object, e As System.EventArgs) Handles Timer2.Tick HilosCompletados() End Sub Private Sub FormulasGrupoI() If VarGlobal.FormulasActivadasGrupoI = True Then t1 = New Thread(AddressOf AccesoLogica.FormulasGrupoI) t1.Start() Else t1.Interrupt() Return End If End Sub Private Sub FormulasGrupoII() If VarGlobal.FormulasActivadasGrupoII = True Then t2 = New Thread(AddressOf AccesoLogica.FormulasGrupoII) t2.Start() Else t2.Interrupt() Return End If End Sub Private Sub FormulasGrupoIII() If VarGlobal.FormulasActivadasGrupoIII = True Then t3 = New Thread(AddressOf AccesoLogica.FormulasGrupoIII) t3.Start() Else t3.Interrupt() Return End If End Sub Private Sub FormulasGrupoIV() If VarGlobal.FormulasActivadasGrupoIV = True Then t4 = New Thread(AddressOf AccesoLogica.FormulasGrupoIV) t4.Start() Else t4.Interrupt() Return End If End Sub Private Sub CancelacionProcesosEnSegundoPlano() Dim t1 As New Thread(AddressOf FormulasGrupoI) Dim t2 As New Thread(AddressOf FormulasGrupoII) Dim t3 As New Thread(AddressOf FormulasGrupoIII) Dim t4 As New Thread(AddressOf FormulasGrupoIV) If t1.ThreadState = 8 Then Return ElseIf t1.ThreadState = Threading.ThreadState.Running Then t1.Interrupt() End If If t2.ThreadState = 8 Then Return ElseIf t2.ThreadState = Threading.ThreadState.Running Then t2.Interrupt() End If If t3.ThreadState = 8 Then Return ElseIf t3.ThreadState = Threading.ThreadState.Running Then t3.Interrupt() End If If t4.ThreadState = 8 Then Return ElseIf t4.ThreadState = Threading.ThreadState.Running Then t4.Interrupt() End If End Sub Public Sub HilosCompletados() HilosCompletado_t3() HilosCompletado_t4() HilosCompletado_t2() HilosCompletado_t1() End Sub Private Sub HilosCompletado_t1() If VarGlobal.FormulasActivadasGrupoI = False Then Timer2.Interval = 5000 Label23.Text = mensajes(0) 'rm.GetString("CargaTotalFormulas") & " I" '"Carga total fórmulas Grupo I" t1 = Nothing 'Vaciamos el hilo. GC.Collect() 'llamada al garbage collection para vaciar la memoria TemporizadorCargaFormulas() Timer2.Stop() End If End Sub Private Sub HilosCompletado_t2() If VarGlobal.FormulasActivadasGrupoII = False Then Label23.Text = mensajes(1) 'rm.GetString("CargaTotalFormulas") & " II" '"Carga total fórmulas Grupo II" t2 = Nothing 'Vaciamos el hilo. GC.Collect() 'llamada al garbage collection para vaciar la memoria End If End Sub Private Sub HilosCompletado_t3() If VarGlobal.FormulasActivadasGrupoIII = False Then Label23.Text = mensajes(2) 'rm.GetString("CargaTotalFormulas") & " III" '"Carga total fórmulas Grupo II" t3 = Nothing 'Vaciamos el hilo. GC.Collect() 'llamada al garbage collection para vaciar la memoria End If End Sub Private Sub HilosCompletado_t4() If VarGlobal.FormulasActivadasGrupoIV = False Then Label23.Text = mensajes(3) 'rm.GetString("CargaTotalFormulas") & " IV" '"Carga total fórmulas Grupo II" t4 = Nothing 'Vaciamos el hilo. GC.Collect() 'llamada al garbage collection para vaciar la memoria End If End Sub


    Se que es un poco largo, pero llevo días con este tema para evitar los bloqueos que se me dan en Formulas :

    Dim t4 As New Thread(AddressOf FormulasGrupoIV). Por ello, no se si el synclock esta haciendo bien su trabajo, ya que entiendo que si tengo bloqueos el FormulasGrupoI y FormulasGrupoII, tendría que funcionar, ya que FormulasHrupoIV puede ir a buscar en algún momento alguna formula del FormulasGrupoII.

    Os ruego por favor que si podéis me digáis si tengo algo mal o como lo puedo solucionar, ya que nose que más hacer par que funcione.

    Muchas gracias a todos.

    Gemma

    martes, 2 de agosto de 2016 8:24

Respuestas

  • Tal como estás usando el SyncLock, no vale para nada. Únicamente dos bloques SyncLock ubicados uno debajo del otro en un código secuencial que no es invocado desde varios hilos. Se ejecutará primero FormulasParaGrupoI y en cuanto regrese esta llamada se ejecutará acto seguido FormulasParaGrupoII. Esto es exactamente lo mismo que habría ocurrido si no hubieses puesto los SyncLock. Tal como están, no protegen nada.

    Normalmente lo que se mete dentro del bloque SyncLock es el código que se ejecuta dentro de un hilo y accede a recursos compartidos con otro hilo que se ejecuta a la vez, con el objetivo de impedir que ambos accedan simultaneamente a esa zona crítica que podría corromper el objeto compartido si dos hilos lo manipulasen a la vez. No sirve para nada poner seguidas dos zonas críticas que siempre se ejecutan una única vez de forma secuencial. El bloqueo se quita inmediatamente en cuanto sales del bloque, no persiste bloqueando otros hilos que mientras tanto se hubieran lanzado desde dentro de la zona crítica.

    • Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 5:34
    martes, 2 de agosto de 2016 19:56
  •  no acabo de entender el correcto funcionamiento de los hilos con synclock, ya que creìa que lo que hay encerrado dentro del bloque está bloqueado.

    No, el SyncLock no bloquea "lo que hay dentro". Lo que bloquea es "la entrada". Pero una vez que se ha entrado, no hay bloqueos sobre el contenido. La idea es que mientras se está ejecutando algo dentro del SyncLock nadie más pueda entrar, se quedaría el otro hilo parado a la entrada del SyncLock esperando a que el hilo anterior salga del bloque. Pero una vez que se está dentro, si desde ahí lanzas varios hilos o accedes a varias variables, nada de todo eso sufre ningún bloqueo.
    • Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 6:46
    miércoles, 3 de agosto de 2016 6:05

Todas las respuestas

  • Tal como estás usando el SyncLock, no vale para nada. Únicamente dos bloques SyncLock ubicados uno debajo del otro en un código secuencial que no es invocado desde varios hilos. Se ejecutará primero FormulasParaGrupoI y en cuanto regrese esta llamada se ejecutará acto seguido FormulasParaGrupoII. Esto es exactamente lo mismo que habría ocurrido si no hubieses puesto los SyncLock. Tal como están, no protegen nada.

    Normalmente lo que se mete dentro del bloque SyncLock es el código que se ejecuta dentro de un hilo y accede a recursos compartidos con otro hilo que se ejecuta a la vez, con el objetivo de impedir que ambos accedan simultaneamente a esa zona crítica que podría corromper el objeto compartido si dos hilos lo manipulasen a la vez. No sirve para nada poner seguidas dos zonas críticas que siempre se ejecutan una única vez de forma secuencial. El bloqueo se quita inmediatamente en cuanto sales del bloque, no persiste bloqueando otros hilos que mientras tanto se hubieran lanzado desde dentro de la zona crítica.

    • Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 5:34
    martes, 2 de agosto de 2016 19:56
  • Hola Alberto:

    Gracias por la respuesta.

    Al final entiendo que no acabo de entender el correcto funcionamiento de los hilos con synclock, ya que creìa que lo que hay encerrado dentro del bloque está bloqueado.

    Voy a dejar este tema que ya me ha llevado demasiado tiempo y ya veré como lo soluciono, posiblemente lo trabaje con los backgroundworkers que me han funcionado antes perfectamente, pero tengo como siempre algún problema de bloqueo.

    Muchas gracias por tu ayuda.

    Gemma

    miércoles, 3 de agosto de 2016 5:37
  •  no acabo de entender el correcto funcionamiento de los hilos con synclock, ya que creìa que lo que hay encerrado dentro del bloque está bloqueado.

    No, el SyncLock no bloquea "lo que hay dentro". Lo que bloquea es "la entrada". Pero una vez que se ha entrado, no hay bloqueos sobre el contenido. La idea es que mientras se está ejecutando algo dentro del SyncLock nadie más pueda entrar, se quedaría el otro hilo parado a la entrada del SyncLock esperando a que el hilo anterior salga del bloque. Pero una vez que se está dentro, si desde ahí lanzas varios hilos o accedes a varias variables, nada de todo eso sufre ningún bloqueo.
    • Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 6:46
    miércoles, 3 de agosto de 2016 6:05
  • Hola Alberto:

    Ya lo he visto mas claro con tu explicación.

    Voy a ver si lo arreglo después de tu información.

    Muchas gracias como siempre.

    Gemma

    miércoles, 3 de agosto de 2016 6:47