Principales respuestas
Problema de funcionamiento de synclock

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
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
-
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.
- Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 6:46
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
-
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
-
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.
- Marcado como respuesta gemma_campillo miércoles, 3 de agosto de 2016 6:46
-